I have a HashMap which I need to parse into JSON:
HashMap<String, Integer> worders = new HashMap<>();
I need to parse it into a JSON array of objects. Current values:
{"and": 100},
{"the": 50}
Needed JSON format:
[
{"word": "and",
"count": 100},
{"word": "the",
"count": 50}
]
I have realised that I need to use a loop to put it into the correct format, but not sure where or how to start.
I have also used the ObjectMapper() to write it as JSON, however, that does not correct the format, thank for help.
You don't actually need to create a formal Java class to do this. We can try creating an ArrayNode, and then adding child JsonNode objects which represent each entry in your original hash map.
HashMap<String, Integer> worders = new HashMap<>();
worders.put("and", 100);
worders.put("the", 50);
ObjectMapper mapper = new ObjectMapper();
ArrayNode rootNode = mapper.createArrayNode();
for (Map.Entry<String, Integer> entry : worders.entrySet()) {
JsonNode childNode = mapper.createObjectNode();
((ObjectNode) childNode).put("word", entry.getKey());
((ObjectNode) childNode).put("count", entry.getValue());
((ArrayNode) rootNode).add(childNode);
}
String jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(rootNode);
System.out.println(jsonString);
Related
currently i have two json body :
1. globaljson
2. companyjson
globaljson :
"dS": {
"a": 5,
"b": false,
"c": 5,
"d": false,
"e": 1,
"f": 5,
"g": 33.528,
"h": false
}
company json :
"dS": {
"a": 90
},
expected output :
"dS": {
"a": 90,
"b": false,
"c": 5,
"d": false,
"e": 1,
"f": 5,
"g": 33.528,
"h": false
}
i tried to do following :
Map<String, Object> map1 = mapper.readValue(companyjson, Map.class);
Map<String, Object> map2 = mapper.readValue(globaljson, Map.class);
Map<String, Object> merged = new HashMap<String, Object>(map1);
merged.putAll(map2);
but this returns
"dS": {
"a": 90
},
im currently using jackson library but couldn't find any method that solves my requirement. i don't want to hard code my keys because key name may change in future.
Before merging ...
map1 must be: {dS={a=90}}
map2 must be: {dS={a=5, b=false, c=5, d=false, e=1, f=5, g=33.528, h=false}}
Then after this line ...
Map<String, Object> merged = new HashMap<String, Object>(map1);
.... merged must be: {dS={a=90}}
Then after this line ...
merged.putAll(map2);
... merged must be {dS={a=5, b=false, c=5, d=false, e=1, f=5, g=33.528, h=false}} since the effect of putAll is to replace the value of the key dS in merged with the value of the key dS in map2. To put it another way; you are merging two maps which both contain a key named dS and hoping that the merge is sensitive to the contents of dS whereas the merge actually just replaces the value of one dS with the value of the other dS.
To get your desired result you have to merge the maps which exist under the dS keys, for example:
Map<String, Object> map1 = mapper.readValue(companyJson, Map.class);
Map<String, Object> map2 = mapper.readValue(globalJson, Map.class);
Map<String, Object> globalMap = (Map) map2.get("dS");
Map<String, Object> companyMap = (Map) map1.get("dS");
globalMap.putAll(companyMap);
The above code results in map2 having the following contents:
{dS={a=90, b=false, c=5, d=false, e=1, f=5, g=33.528, h=false}}
The easiest option is to use JsonNode instead of Map and jackson mapper to perform merge.
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readValue(json1, JsonNode.class);
JsonNode node2 = mapper.readValue(json2, JsonNode.class);
JsonNode result = mapper.updateValue(node, node2);
// if you really need a map
Map merged = mapper.convertValue(result, Map.class);
Alternative version
JsonNode node = mapper.readValue(json1, JsonNode.class);
ObjectReader updater = mapper.readerForUpdating(node);
JsonNode result = updater.readValue(json2);
I have a need to parse a JSON string containing Objects, but there can also be Arrays in the JSON, which I don't need, and it's currently crashing with:
com.google.gson.JsonSyntaxException:
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY
If I remove all the Arrays from the JSON, it works perfectly fine to parse the JSON with my POJO using the following code:
Type type = new TypeToken<Map<String, UsersPOJO>>(){}.getType();
Map<String, UsersPOJO> myUsers = gson.fromJson(JSONString, type);
But I'm having no luck parsing whenever there's Arrays in the JSON. I don't need, nor do I want to parse the Arrays, but if it's necessary, parsing the Arrays and then discarding the result would be okay.
How do I accomplish this with Gson? Or any other Java JSON library for that matter. Gson isn't a requirment.
This is an example of the JSON I'd be parsing:
{
"1002001":{
"level":2,
"name":"CaptKrunch",
"uid":1002001,
"user":{
"age":21,
"city":"None",
"country":"United States",
"creation":1269969663
},
"meta":{
"score":1762,
"rank":78
}
},
"1003001":{
"level":11,
"name":"LtRaine",
"uid":1003001,
"user":{
"age":35,
"city":"LA",
"country":"United States",
"creation":1269369663
},
"meta":{
"score":11562,
"rank":11
}
},
"tags_1002001": [
"conqurer",
"almighty"
]
}
You can skip array, if parse JSON string to JsonElement and iterate all elements:
Gson gson = new Gson();
//Type type = new TypeToken<Map<String, UsersPOJO>>(){}.getType();
//Map<String, UsersPOJO> myUsers = gson.fromJson(jsonString, type);
JsonParser parser = new JsonParser();
JsonElement topElement = parser.parse(jsonString);
Map<String, UsersPOJO> myUsers = new HashMap<>();
for (Map.Entry<String, JsonElement> entry : topElement.getAsJsonObject().entrySet()) {
if (entry.getValue().isJsonArray()) {
//skip or process array
} else {
myUsers.put(entry.getKey(), gson.fromJson(entry.getValue(), UsersPOJO.class));
}
}
I have a JSON
{
"info": {
"info1": {
"age": "30",
"city": "New york"
},
"info2": {
"sleeping": "false"
},
"info3": {
"shopping": "false",
"eating": "Buger"
}
},
"data": [{
"name": "XYZ",
"email": "xyz#123.com"
}, {
"name": "ABC",
"email": "ABC#123.com"
}]
}
I need to make a parser that would be generic, and extract names for objects, arrays and individual key pair text.
I will be generating a query using these values.
Only "info" and "data" tags will be fixed rest all can change. We can have empty "info" or different children like "info1", "info2".... "info5" ...
Similarly, individual "info" child can have multiple children like "info1" can have 2 entries or 4 entries.
I tried using jackson library, but not able to traverse the complete json.
UPDATE: using jackson 2.7.2 (latest)
Used following code
JsonFactory factory = new JsonFactory();
ObjectMapper mapper = new ObjectMapper(factory);
JsonNode rootNode = mapper.readTree(jsonString);
Iterator<Map.Entry<String, JsonNode>> fieldsIterator = rootNode.fields();
while (fieldsIterator.hasNext()) {
Map.Entry<String, JsonNode> field = fieldsIterator.next();
System.out.println("Key: " + field.getKey() + "\tValue:" + field.getValue());
}
It iterated for the "info" and "data" key. Need to iterate over complete json.
JsonNode can be used to parse whole jsonObject. JsonNode get method can be used to traverse the given JSON.
e.g. :
ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = mapper.readTree(data);
JsonNode infoNode = rootNode.get("info");
Iterator<Map.Entry<String, JsonNode>> infoFieldsIterator = infoNode.fields();
while (infoFieldsIterator.hasNext()) {
Map.Entry<String, JsonNode> field = infoFieldsIterator.next();
System.out.println("Key: " + field.getKey() + "\tValue:" + field.getValue());
}
JsonNode dataNode = rootNode.get("data");
for (int i = 0; i < dataNode.size(); i++) {
JsonNode dataNodeNum = dataNode.get(i);
Iterator<Map.Entry<String, JsonNode>> dataFieldsIterator = dataNodeNum.fields();
while (dataFieldsIterator.hasNext()) {
Map.Entry<String, JsonNode> field = dataFieldsIterator.next();
System.out.println("Key: " + field.getKey() + "\tValue:" + field.getValue());
}
}
For more info please check here.
Why not try GSON.
https://github.com/google/gson
You can use models inside models to achieve what you need.
ALL you need to do is serialise data using gson as follows
#SerializedName("info")
private infomodel info;
you can create a seperate model called info model which contains serialized name for its objects.
use the below code to get object from json
Gson gson=new Gson();
Model yourModel=gson.fromJson(<your json object as string>);
I'd like to convert
Map<long,long> myMap to
myMap : [{"key": 1, "value": 100},
"key": 2, "value": 200}}
Is it possible? I am using Jackson and default behaviour is:
myMap : [{"1" : 100},
"2" : 200}}
It's not possible with a map. However you can create a custom class with key and value as fields and then populate a Collection with instances of that class. On JSON serialization with Jackson the result will be the way you want it.
try this:
ObjectMapper mapper = new ObjectMapper();
String json = "";
Map<String, String> map = new HashMap<String, String>();
map.put("name", "mkyong");
map.put("age", "29");
//convert map to JSON string
json = mapper.writeValueAsString(map);
I am using GSON to serialize Java object.
I have a Java class with following properties.
String property1;
Map<String, HashMap> property2 = new HashMap<>();
Map<String, ArrayList<String>> property3 = new HashMap<>();
Map<String, String[]> property4 = new HashMap<>();
I want to convert this to Json. Because of the maps with HashMaps inside, it has become difficult. I know I can get Json of a map with gsonObject.toJson(map). But I want all these properties in the Json Object. (all in one. not Concatenating many objects)
Can anyone help me to get this done?
I don't see what the problem is. Gson can serialize Maps just fine.
Assuming your class is named Test
Test test = new Test();
test.property1 = "some value";
HashMap<String, Integer> map = new HashMap<>();
map.put("one", 1);
map.put("fourty two", 42);
test.property2.put("property2-key", map);
ArrayList<String> strings = new ArrayList<>(Arrays.asList("string1",
"string2", "string3"));
test.property3.put("property3-key", strings);
String[] stringArray = { "array1", "array2", "array3" };
test.property4.put("property4-key", stringArray);
Gson gson = new Gson();
String json = gson.toJson(test);
System.out.println(json);
It generates the following
{
"property1": "some value",
"property2": {
"property2-key": {
"fourty two": 42,
"one": 1
}
},
"property3": {
"property3-key": [
"string1",
"string2",
"string3"
]
},
"property4": {
"property4-key": [
"array1",
"array2",
"array3"
]
}
}