From the API response, I'm parsing the JSON
String myData = jsonSlurper.parseText(responseBody)
Map parsedBiblio = jsonSlurper.parseText(myData)
below is the output of parsedBiblio
{"Data": {"AppNumber": "15671037", "CustomerNumber": "81744", "Date": "08-07-2017", "Status": "Active"},
"Applicants": [{"Name": "abcd Inc.", "Address": "xxx, CA (US)"}],
below is the code of retrieving the Data key and corresponding value
Map<Object, Object> innerMap = parsedBiblio.get("Data")
for (Object objectName : innerMap.keySet()) {
println("Key: " + objectName + " Value: "+ innerMap.get(objectName) +".");
}
Let me know how I can retrieve the Applicants key and the corresponding values, because this is map<string,List<string> format, so I will declare the innermap in the below format
Map<String, List<String>> innerMapApplicant = parsedBiblio.get("Applicants")
I get this error
Cannot cast object '[{Address=xxx, CA (US), Name=abcd Inc.}]' with class 'java.util.ArrayList' to class 'java.util.Map' due to: groovy.lang.GroovyRuntimeException: Could not find matching constructor for: java.util.Map(groovy.json.internal.LazyMap)
I think you should try retrieving Applicant as follow:
List<Map<String,String>> applicantList = = parsedBiblio.get("Applicants")
You can fetch key and value in the map as follow :
for(Map<String,String> applicantMap: applicantList)
{
for (Object objectName : applicantMap.keySet())
{
println("Key: " + objectName + " Value: "+ applicantMap.get(objectName) +".");
}
}
Don't understand why you double parse a String
If responseBody is an string, you can write:
def json = jsonSlurper.parseText(responseBody)
println json.Data.Applicants.Name
println json.Data.Applicants.Address
Related
I'm receiving the following JSON object and I'm only interested in the errors. I can log to the console each key and value. The issue is for example 'Email' key has 2 x values, how can i create a map or list so every value has its own key and remove the JSON formatting?
{
"errors":
{
"Email":["'Email' must not be empty.","'Email' is not a valid email address."],
"Company":["'Company' must not be empty."],
"LastName":["'Last Name' must not be empty."],
"Password":["'Password' must not be empty."],
"FirstName":["'First Name' must not be empty."],
"Telephone":["'Telephone' must not be empty."]
},
"title":"One or more validation errors occurred.",
"status":400,
"traceId":"80005307-0001-5d00-b63f-84710c7967bb"
}
In codenameone i'm parsing using JSON parser in to a map of string, object:
Map<String,Object> result = new JSONParser().parseJSON(new InputStreamReader(new ByteArrayInputStream(r.getResponseData()), "UTF-8"));
Map<String,Object> value = (Map<String,Object>) result.get("errors");
for (Map.Entry<String, Object> entry : value.entrySet()) {
Log.p(entry.getKey());
Log.p(entry.getValue().toString())
}
The value of the email field is a list, as indicated by the [] square brackets.
Since it appears that all the fields of errors have lists of strings, you should simple cast to Map<String, List<String>>, so you don't have to cast any further.
Map<String,Object> result = /*result of parsing JSON input*/;
#SuppressWarnings({ "rawtypes", "unchecked" })
Map<String, List<String>> errors = (Map) result.get("errors");
for (Entry<String, List<String>> error : errors.entrySet()) {
String name = error.getKey();
List<String> messages = entry.getValue();
Log.p(name);
for (String message : messages)
Log.p(" " + message);
}
That's your thing, brother, I just changes some names for better readability:
Map<String,Object> errors = (Map<String,Object>) map.get("errors");
Collection<Object> values = errors.values();
values.stream().flatMap(x->((ArrayList<String>)x).stream()).forEach(value -> {
String key = errors.entrySet()
.stream()
.filter(tempEntry -> ((ArrayList<String>)tempEntry.getValue()).contains(value))
.findAny()
.get()
.getKey();
System.out.println(key + value);
});
So ye from that you can create a Collection of entries. Currently we print them, but you can skip ".getKey()" and "System.out" and start adding them to a collection.
I am trying to receive message attributes from Amazon SQS with the following code :
Map<String, com.amazonaws.services.sqs.model.MessageAttributeValue> attributes = new HashMap<String, com.amazonaws.services.sqs.model.MessageAttributeValue>();
attributes = message.getMessageAttributes();
for(String key: attributes.keySet()){
System.out.println(key + " - "+ attributes.get(key));
}
and it returns the output:
project - {StringValue: 25,StringListValues: [],BinaryListValues: [],DataType: String}
I want to get only the value 25. How do I do that?
Try this:
attributes.get("project").getStringValue()
References:
How to extract from a Map the value of a given key?
How to extract a String Value of a given MessageAttributeValue?
Because that's the object of value type com.amazonaws.services.sqs.model.MessageAttributeValue declared in your Map .
You need to get the value out of that object like the way you would normally do :
for(String key: attributes.keySet()){
com.amazonaws.services.sqs.model.MessageAttributeValue object = attributes.get(key);
//some method to get that 25 value
System.out.println(key + " - "+ object.getStringValue());
}
You need to loop on your map here is an example to show you how to get the values of the map:
I have a : Map<String, Object> map = new HashMap<String, Object>();
for (Entry<String, Object> entry : map.entrySet()) {
System.out.println("entry key : "+entry.getKey());
System.out.println("Object value :"+entry.getValue());
}
use this (library org.json.JSONObject; [java-json.jar])
Map<String, com.amazonaws.services.sqs.model.MessageAttributeValue> attributes = new HashMap<String, com.amazonaws.services.sqs.model.MessageAttributeValue>();
attributes = message.getMessageAttributes();
for(String key: attributes.keySet()){
System.out.println(key + " - "+ attributes.get(key));
try {
JSONObject json = new JSONObject(attributes.get(key));
System.out.println(json.get("StringValue"));
} catch (JSONException e) {
e.printStackTrace();
}
}
I have a need to serialize a JSON without being attached to particular schema for resulting object, e.g., to some generic set/map/hashmap.
As input, I have a string with a JSON. I do not know schema for that JSON.
As output, I want a Java Object such as Hashmap or similar that has key-value serialization of input.
Note that input JSON has both basic fields and Array/List inside it.
I have to use Java and Jackson (or some other library). How I possibly can do that?
Jackson data binding is able to read any json input into a Map with String key and Object value (that can be also a map or collection). You just tell the mapper that you would like to read the json into a map. You do that by giving the mapper the appropriate type reference:
import java.util.*;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Test
{
public static void main(String[] args)
{
try {
String json = "{ "
+ "\"string-property\": \"string-value\", "
+ "\"int-property\": 1, "
+ "\"bool-property\": true, "
+ "\"collection-property\": [\"a\", \"b\", \"c\"], "
+ "\"map-property\": {\"inner-property\": \"inner-value\"} "
+ "}";
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> map = new HashMap<>();
// convert JSON string to Map
map = mapper.readValue(json, new TypeReference<Map<String, Object>>(){});
System.out.println("input: " + json);
System.out.println("output:");
for (Map.Entry<String, Object> entry : map.entrySet()) {
System.out.println("key: " + entry.getKey());
System.out.println("value type: " + entry.getValue().getClass());
System.out.println("value: " + entry.getValue().toString());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
output:
input: { "string-property": "string-value", "int-property": 1, "bool-property": true, "collection-property": ["a", "b", "c"], "map-property": {"inner-property": "inner-value"} }
output:
key: string-property
value type: class java.lang.String
value: string-value
key: int-property
value type: class java.lang.Integer
value: 1
key: bool-property
value type: class java.lang.Boolean
value: true
key: collection-property
value type: class java.util.ArrayList
value: [a, b, c]
key: map-property
value type: class java.util.LinkedHashMap
value: {inner-property=inner-value}
I have a simple JSON object I wish to parse in Play, I am currently trying the following but having no luck:
HashMap<String,Object> result = new ObjectMapper().readValue(stringBuilder.toString(), HashMap.class);
My JSON Object looks like the following:
[{"id":"537b4f2e30047c51863094dd","from":"jacob","to":"duncan","subject":"Welcome to the message system!","message":"Hello World"},{"id":"537bb23930044f26cfd24464","from":"jacob","to":"duncan","subject":"Welcome to the message system!","message":"Hello World"}]
Can anybody provide an example on how to parse and iterate over this?
Play 2 uses Jackson API for JSON, so you should use it
Sample:
String jsonString = "[{\"id\":\"537b4f2e30047c51863094dd\",\"from\":\"jacob\",\"to\":\"duncan\",\"subject\":\"Welcome to the message system!\",\"message\":\"Hello World\"},{\"id\":\"537bb23930044f26cfd24464\",\"from\":\"jacob\",\"to\":\"duncan\",\"subject\":\"Welcome to the message system!\",\"message\":\"Hello World\"}]";
JsonNode node = Json.parse(jsonString);
if (node.isArray()) {
Iterator<JsonNode> elements = node.elements();
while (elements.hasNext()) {
JsonNode obj = elements.next();
debug(
"Message with ID: " + obj.get("id")
+ " from: " + obj.get("from")
+ " to: " + obj.get("to")
+ " subject: " + obj.get("subject")
+ " message: " + obj.get("message")
);
}
}
Tip: It was refactored some time ago, so depending on used Play version check Codehaus Jackson or FasterXML Jackson APIs
It looks like you've got a list, where each entry is a map key value pairs.
You can use a standard json parser to convert it into an object like this:
String json = "[{\"id\":\"537b4f2e30047c51863094dd\",\"from\":\"jacob\",\"to\":\"duncan\",\"subject\":\"Welcome to the message system!\",\"message\":\"Hello World\"},{\"id\":\"537bb23930044f26cfd24464\",\"from\":\"jacob\",\"to\":\"duncan\",\"subject\":\"Welcome to the message system!\",\"message\":\"Hello World\"}]";
Type listType = new TypeToken<List<Map<String, Object>>>(){}.getType();
List<Map<String, Object>> data = new Gson().fromJson(json, listType);
Then you can iterate over the List and each Map as normal:
for (Map<String, Object> map : data) {
for (Map.Entry<String, Object> entry : map.entrySet()) {
// do stuff
}
}
P.S.
It looks like all your value data is also in String form, so you might want to consider making a Map<String, String> instead of Map<String, Object> if that's actually the case.
I am using this code below to merge JSON data into a template, to get HTML:
Template:
String schema = "<h1>{{header}}</h1>"
+ "{{#bug}}{{/bug}}"
+ "{{#items}}"
+ "{{#first}}"
+ "<li><strong>{{title}}</strong>
+ </li>"
+ "{{/first}}"
+ "{{#link}}"
+ "<li><a href=\"{{url}}\">{{name}}
+ </a></li>"
+ "{{/link}}"
+ "{{/items}}"
+ "{{#empty}}"
+ "<p>The list is empty.</p>"
+ "{{/empty}}";
JSON object:
try {
String template = "{\"header\": \"Colors\", "
+ "\"items\": [ "
+ "{\"name\": \"red\", \"first\": true, \"url\": \"#Red\"}, "
+ "{\"name\": \"green\", \"link\": true, \"url\": \"#Green\"}, "
+ "{\"name\": \"blue\", \"link\": true, \"url\": \"#Blue\"}"
+ " ], \"empty\": false }";
JSONObject jsonWithArrayInIt = new JSONObject(template);
JSONArray items = jsonWithArrayInIt.getJSONArray("items");
Map<String,String> ctx = new HashMap<String,String>();
ctx.put("foo.bar", "baz");
Mustache.compiler().standardsMode(true).compile("{{foo.bar}}").execute(ctx);
System.out.println("itemised: " + items.toString());
} catch(JSONException je) {
//Error while creating JSON.
}
I pass a map of data to get Mustache to work. The method looks like this:
public static Map<String, Object> toMap(JSONObject object)
throws JSONException {
Map<String, Object> map = new HashMap();
Iterator keys = object.keys();
while (keys.hasNext()) {
String key = (String) keys.next();
map.put(key, fromJson(object.get(key)));
}
return map;
}
I am following a Mustache Guide to get the Mustache autoformation. But I don't know how to get the result I am expecting. The output should be as follows:
<h1>Colors</h1>
<li><strong></strong></li>
<li>green</li>
<li>blue</li>
I think you need to rethink your Mustache template slightly. The jMustache library (which I assume you are using) seems to always treat {{# entities as lists and iterate their contents, regardless of the data type passed in.
Something like this should work:
<h1>{{header}}</h1>
{{#items}}
<li>
{{#url}}<a href="{{.}}">{{/url}}
{{^url}}<strong>{{/url}}
{{caption}}
{{#url}}</a>{{/url}}
{{^url}}</strong>{{/url}}
</li>
{{/items}}
{{^items}}
<p>The list is empty.</p>
{{/items}}
This will produce an HMTL anchor only if a "link" value is provided, thus avoiding the jMustache if condition issue. So the JSON model would look something like this:
{
"header": "Colors",
"items": [
{"caption": "title"},
{"caption": "red", "url": "#Red"},
{"caption": "green", "url": "#Green"},
{"caption": "blue", "url": "#Blue"}
]
}
Finally, you will need to convert your JSON to something jMustache understands. I've never seen or heard of the "HTTPFunctions" class in any library I've used, but I've done some similar mapping using Gson in the past. Note that this is a very simple implementation and you may need to extend it to fit your needs:
private Map<String, Object> getModelFromJson(JSONObject json) throws JSONException {
Map<String,Object> out = new HashMap<String,Object>();
Iterator it = json.keys();
while (it.hasNext()) {
String key = (String)it.next();
if (json.get(key) instanceof JSONArray) {
// Copy an array
JSONArray arrayIn = json.getJSONArray(key);
List<Object> arrayOut = new ArrayList<Object>();
for (int i = 0; i < arrayIn.length(); i++) {
JSONObject item = (JSONObject)arrayIn.get(i);
Map<String, Object> items = getModelFromJson(item);
arrayOut.add(items);
}
out.put(key, arrayOut);
}
else {
// Copy a primitive string
out.put(key, json.getString(key));
}
}
return out;
}
This basic JUnit test demonstrates the theory: http://www.pasteshare.co.uk/p/841/
Just use
Map<String, Object> s = HTTPFunctions.toMap(new JSONObject(template));