Using HashMap to create complex JSON - java

I have spent a few days googling this various ways and don't see any that give examples of using HashMap - instead they all refer to Jackson or GSON. I am not able to use these as they cause an issue in Jenkins that will not be addressed (basically everything is super locked down and the work place will not "open" up alternatives)
I have a JSON body that I am attempting to send to a create record API.
For simple JSON body the process is pretty straightforward:
Desired JSON:
{
"owner": {
"firstName": "Steve",
"lastName": "Guy",
"Hair": "brown",
"Eyes": "yes"
"etc": "etc"
},
"somethingElse": "sure"
}
would look like
Map<String,Object> jsonRequest = new HashMap<>();
Map<String,String> ownerMap = new HashMap<>();
HashMap<Object, String> OwnerMap = new HashMap<Object, String>;
OwnerMap.put("firstName","Steve");
OwnerMap.put("lastName","Guy");
OwnerMap.put("Hair","brown");
OwnerMap.put("Eyes","yes");
OwnerMap.put("etc","etc");
jsonRequest.put("owner", OwnerMap);
jsonRequest.put("somethingElse", "sure");
Easy enough
If the JSON gets slightly more complex, I can't seem to figure it out.. and again I cannot use any other dependency for this.
so if I have a JSON Body that I need to send :
{
"customer": {
"address": [
{
"address": "Blah"
}
]
},
"anotherThing": "thing"
}
the same pattern does not work.
Map<String,Object> jsonRequest = new HashMap<>();
Map<String,String> ownerMap = new HashMap<>();
HashMap<Object, String> addressMap = new HashMap<Object, String>;
addressmap.put("address","Blah");
jsonRequest.put("address", addressMap);
jsonRequest.put("owner", OwnerMap);
jsonRequest.put("anotherThing", "thing");
returns as:
{
"owner": {
},
"anotherThing": "thing",
"address": {
"address": "Blah"
}
}

You seem to assume that the inner (for want of a better word) Maps need to be Map<*, String>, and that Map and String are the only things which extend Object.
Something like the following should work fine:
Map<String, Object> json = new HashMap<>();
Map<String, Object> customer = new HashMap<>();
// Could make this a Map<String, Object>[] (array) depending
// on json library used... You don't specify.
List<Map<String, Object>> address = new ArrayList<>();
Map<String, Object> innerAddress = new HashMap<>();
innerAddress.put("address", "Blah");
address.add(innerAddress);
customer.put("address", address);
json.put("customer", customer);
json.put("anotherThing", "thing");

Related

Convert JSONArrays into Map using Java

Trying to write a java class which convert JSON into Map by giving key. Sample method format and steps are below:
public Map<String, Map<String, String> convert(String jsonBody, String key){
Map<String, Map<String, String>> dataMap = new HashMap<String, Map<String, String>>();
Map<String, String> singleEntry = new HashMap<String, String>();
//Iterator<String> --get key from jsonBody
while(itr.hasNext()){
for(upto arary count){
singleEntry.put(jsonBody.getKey(i), jsonBody.getValue(i));
}
dataMap.put(itr.next(), singleEntry);
}
System.out.println(dataMap);
return data;
}
Sample JSON
[
{
"id": 146,
"Name": "John",
"LastName": "Mack",
},
{
"id": 148,
"Name": "Sam",
"LastName": "Rick",
}
]
Expected Output:
id -146, {id=146, Name = John, LastName =Mack}
id -148, {id=148, Name = Sam, LastName =Rick}
Please suggest best API and correct approach. Thanks in Advance.
See here for how to convert a json node to a Map.
See here about how to convert the json array to a map.

Adding multiple Json node into one Using Jackson

I am trying to create Json Structure like the below one
{
"properties": {
"a": {
"b": 1,
"c": "2",
"d": 3,
"e": 4
},
"f": {
"g": 5,
"h": "6",
"i": 7,
"j": 8
}
}
}
but I could not.
I have written following code
for(Annotation a : annotationList) {
ObjectNode objectNode1 = readAnnotation(a);
String name= getName(key);
objectNode.putPOJO(name, objectNode1);
propertiesObjectNode.put("properties", objectNode1);
}
to create a JSON but eventually i have only one node in properties.
I got following Json
{
"properties" : {
"f" : {
"g" : 5,
"h" : "6",
"i" : 7,
"j" : 8
}
}
}
propertiesObjectNode.put("properties", objectNode1);
This line is inside a for loop, so you are overwriting it with each iteration. At the end you are left with just 1 node which was a result of last iteration.
Maybe I'm off base here, but if you are using Jackson, why not use the ObjectMapper class. It will convert a POJO to JSON.
ObjectMapper mapper = new ObjectMapper();
MyPojo pojo = new MyPojo();
String json = mapper.writeValueAsString(pojo);
If you wanted to setup something like you have, jackson can take the map and output the json version.
You would have something like:
Map<String, Object> a = new HashMap<String, Object>();
a.put("b", 1);
a.put("c", "2");
Map<String, Object> f = new HashMap<String, Object>();
f.put("g", 5);
f.put("h", "6");
Map<String, Object> propWrapper = new HashMap<String, Object>();
propWrapper.put("a", a)
propWrapper.put("f", f)
Map<String, Object> props = new HashMap<String, Object>();
props.put("properties", props);
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(props);
And that should output the structure you're looking for. It would be better to use your own POJO to get a more meaning full structure, but this should provide an idea.

Converting Nested json into dot notation json

I have a service from where I get a json string response like as shown below
{
"id": "123",
"name": "John"
}
I consume the rest call using HttpClient and converts the json string to Map<String, String> like as shown below.
String url= "http://www.mocky.io/v2/5979c2f5110000f4029edc93";
HttpClient client = HttpClientBuilder.create().build();
HttpGet httpGet = new HttpGet(url);
httpGet.setHeader("Content-Type", "application/json");
HttpResponse httpresponse = client.execute(httpGet);
String response = EntityUtils.toString(httpresponse.getEntity());
ObjectMapper mapper = new ObjectMapper();
Map<String, String> map = mapper.readValue(response, new TypeReference<Map<String, String>>(){});
The conversion from json string to HashMap is working fine, but actually my requirement was sometimes there can be some nested json within the main json, for example in the below json I am having an additional address key which is again a nested json having city and town details.
{
"id": "123",
"name": "John",
"address": {
"city": "Chennai",
"town": "Guindy"
}
}
If any nested json comes I need the make the json like as shown below
{
"id": "123",
"name": "John",
"address.city": "Chennai",
"address.town": "Guindy"
}
Currently I am using jackson library, but open to any other library which will give me this feature out of box
Can anyone help me by giving some suggestion on this.
Here is a recursive method that will flatten a nested Map with any depth to the desired dot notation. You can pass it to Jackson's ObjectMapper to get the desired json output:
#SuppressWarnings("unchecked")
public static Map<String, String> flatMap(String parentKey, Map<String, Object> nestedMap)
{
Map<String, String> flatMap = new HashMap<>();
String prefixKey = parentKey != null ? parentKey + "." : "";
for (Map.Entry<String, Object> entry : nestedMap.entrySet()) {
if (entry.getValue() instanceof String) {
flatMap.put(prefixKey + entry.getKey(), (String)entry.getValue());
}
if (entry.getValue() instanceof Map) {
flatMap.putAll(flatMap(prefixKey + entry.getKey(), (Map<String, Object>)entry.getValue()));
}
}
return flatMap;
}
Usage:
mapper.writeValue(System.out, flatMap(null, nestedMap));

Java : Sort JSON String using key

I have a String which is in JSON format. I need to sort this JSON string using attributes but am unable to do it. JSON String is created by reading a CSV file. I do not want to read the CSV again and have to implement it using JSON String only. Is there a way to do that? Please let me know.
JSON String format is :
[
{
"address": "some address",
"name": "some name",
"phone": "some phone",
"age": "some age",
"SSN": "some SSN"
},
{
"address": "abc",
"name": "def",
"phone": "ghi",
"age": "jkl",
"SSN": "mno"
}
]
Please explain.
You can convert the JSONstring into a TreeMap with a Comparator you implement to compare by value, and then convert this TreeMap back to JSON.
See how to create a value Comparator here:
http://www.programcreek.com/2013/03/java-sort-map-by-value/
And then use ObjectMapper to convert the JSON into a map the the map back to JSON:
String json = "{\"address\" : \"def\","
+ "\"name\" : \"ghi\","
+ "\"phone\" : \"jkl\","
+ "\"age\" : \"def\","
+ "\"SSN\" : \"abc\"}";
Map<String, String> jsonMap = new HashMap<String, String>();
ObjectMapper mapper = new ObjectMapper();
jsonMap = (mapper.readValue(json, Map.class));
Comparator<String> comparator = new ValueComparator(jsonMap);
Map<String, String> treeMap = new TreeMap<String, String>(comparator);
treeMap.putAll(jsonMap);
String sortedJson = mapper.writeValueAsString(treeMap);
System.out.println(sortedJson);
Result:
{"SSN":"abc","address":"def","name":"ghi","phone":"jkl"}
Comparator:
public class ValueComparator implements Comparator<String> {
Map<String, String> map = new HashMap<String, String>();
public ValueComparator(Map<String, String> map){
this.map = map;
}
#Override
public int compare(String s1, String s2) {
return map.get(s1).compareTo(map.get(s2));
}
}

Android - Converting nested Maps to JSON String

My app does HTTP requests using this GsonRequest implementation.
Some of the requests parameters are not simple string keys and string values, but some values can be a map too.
For instance:
{
"Key1" : "value",
"Key2" : {
"Key2.1" : "value",
"Key2.2" : "value",
"Key2.2" : "value"
},
"Key3" : "value"
}
The JSON parameters above can be built using HashMaps like this:
Map<String, String> subMap = new HashMap<String, String>();
subMap.put("Key2.1", "value");
subMap.put("Key2.2", "value");
subMap.put("Key2.3", "value");
Map<String, String> map = new HashMap<String, String>();
map.put("Key1", "value");
map.put("Key2", subMap.toString());
map.put("Key3", "value");
And then I call GsonRequest and pass map.
However, when the request is made, the JSON sent is actually:
{
"Key1" : "value",
"Key2" : "{Key2.1 = value, Key2.2 = value, Key2.2 = value}", <-- This is wrong
"Key3" : "value"
}
I tried to nest the maps using a JSONObject, with no success:
map.put("Key2.2", new JSONObject(subMap).toString());
will produce the JSON:
...
"Key2" : "{\"Key2.1\" : \"value\", \"Key2.2\" : \"value\", \"Key2.2\" : \"value\"}",
...
This one looks better, if I could escape the slashes it'd be right, but no.
How can I nest the maps properly and get the JSON correctly?
After thinking for a while, I realized that nesting Strings was wrong and that should not be used. But I was using that because the class Request, which my GsonRequest extends, requires a HashMap<String, String> map for the parameters.
What I did was to force the passage of a HashMap<String, Object> map. I didn't expected it to work, but I needed to give it a try. And it did work.

Categories

Resources