Merge multiple Collection<String> into one JSON String using GSON - java

Is there a way to merge different String-Collections into one JSON 'String'?
I would like to have a JSON String that looks like this:
{"vendor":[Sun, HP, IBM],"product":[bla, bla, bla],"availability":[high, mid, low],"capacity":[bla, bla, bla], ...}
This is a part of my Java Code:
Collection<String> vendor = bh.getAllVendors();
Collection<String> product = bh.getProductsForVendor(vendor);
Collection<String> availability = bh.getAllAvailabilities();
Collection<String> capacity = bh.getCapacityForVendor(vendor);
Collection<String> signaling = bh.getSignalingForVendor(vendor);
Collection<String> backup = bh.getBackupForVendor(vendor);
Gson gson = new Gson();
Any help would be appreciated.

It would be easiest if you add them to a map:
Gson gson = new Gson();
Map<String, Collection<String>> map = new HashMap<>();
map.put("vendor", vendor);
map.put("product", product);
//etc
System.out.println(gson.toJson(map));
produces
{"product":["bla","bla","bla"],"vendor":["Sun","IBM","HP"]}

Create a new class:
Class MyJSONObject
{
Collection<String> vendor;
Collection<String> product;
Collection<String> availability;
//...
//...
}
Then assign your data to those attributes in an instance of MyJSONObject.
Then serialize that instance:
gson.toJson (myJSONObjectInstance);
Read the 'Object Examples' section of this GSON documentation.

Related

How to parse following json using Gson?

I have seen similar questions about parsing json with dynamic keys, but could not figure out how to parse the following json:
{
"unknown":
{
"id":3980715,
"name":"namename",
"profileIconId":28,
"revisionDate":1451936993000
}
}
Here, the "unknown" key is dynamic, it can be anything. We do not know what it is.
I tried the following class:
public class MyResponseClass {
private Map<String, Object> myResponse;
//Getter and setter
}
But myResponse becomes null after using gson like the following:
return gson.fromJson(response, MyResponseClass.class);
So, how can i do this?
Thanks.
I could manage to parse it like the following:
Type mapType = new TypeToken<Map<String, MyResponseClass>>() {}.getType();
Map<String, MyResponseClass> map = gson.fromJson(response, mapType);
and then iterated over map to get what I want.
Add an annotation to the field myResponse.
public class MyResponseClass {
#SerializedName("unknown")
private Map<String, Object> myResponse;
//Getter and setter
}
Try this:
// String jsonStr = ...;
Gson gson = new Gson();
Map<String, Object> jsonData = new HashMap<String, Object>();
jsonData = (Map<String, Object>)gson.fromJson(jsonStr, Object.class);
Your JSON data will be stored in Map<String, Object> (which is the simpliest way to store JSON data in Java).
So in this map at unknown key you will have another map with id, name etc.

Conversion between JSON with wrapped structure and pojo with flattended structure

I have a JSON structure that incorporates a wrapping level that I don't have in my POJOs. Like so:
JSON:
{
"category1": {
"cat1Prop1": "c1p1",
"cat1Prop2": "c1p2",
"cat1Prop3": "c1p3"
},
"category2": {
"cat2Prop1": "c2p1",
"cat2Prop2": "c2p2"
},
"category3": {
"cat3Prop1": "c3p1",
"cat3Prop2": "c3p2",
"cat3Prop3": "c3p3"
},
"category4": {
"cat4Prop1": "c4p1"
}
}
POJO:
public class MyPojo {
private String cat1Prop1;
private String cat1Prop2;
private String cat1Prop3;
private String cat2Prop1;
private String cat2Prop2;
private String cat3Prop1;
private String cat3Prop2;
private String cat3Prop3;
private String cat4Prop1;
// Getters / setters, etc...
}
As you can see, the JSON have a "category" level (that for different reasons I don't want to have in my Pojo).
I'm looking for a way to use Jackson for serializaion/deserialization to handle this in a smooth way.
I'm aware that Jackson has a #JsonUnwrapped annotation that kind of handles the opposite. I'm also aware that there is a feature request for a "#JsonWrapped" annotation that I think would solve my case.
Thankful for any input or help regarding this, as I have been looking around quite a bit. Also, any suggestions on how this could be accomplished using any other library (like gson, flexjson, etc) is also interesting.
You can try with this algorithm:
Read JSON as Map.
Flatten map
Use ObjectMapper to convert Map into POJO.
Implementation could looks like this:
ObjectMapper mapper = new ObjectMapper();
Map<String, Map<String, String>> map = mapper.readValue(new File("X:/test.json"), Map.class);
Map<String, String> result = new HashMap<String, String>();
for (Entry<String, Map<String, String>> entry : map.entrySet()) {
result.putAll(entry.getValue());
}
System.out.println(mapper.convertValue(result, MyPojo.class));

conversion of array list to json object string

I have a model class method which returns a list of objects which contains all the registered user details. I want to fetch the list resturned by all() method and convert the data into JSON object and pass it to the view like a string. How can I do this conversion of this array list to JSON object?
I was unable to do this by below:
ObjectMapper mapper = new ObjectMapper();
JSONObject json = new JSONObject();
JsonNodeFactory jsonnode = JsonNodeFactory.instance;
ObjectNode result = new ObjectNode(jsonnode);
for (int i = 0; i < list.size(); i++) {
json.put(list.get(i).fname, list.get(i));
System.out.println(json.get("fname"));
}
#Entity
class Mydata extends Model {
#Id
public Long Id;
public String fname;
public String lname;
public String city;
public String state;
/****************** READ/select OPERATION *****************/
public static Finder < Long, Mydata > finder = new Finder(Long.class, Mydata.class);
public static List < Mydata > all() {
return finder.all();
}
public static void createuser(Mydata user) {
user.save();
}
}
To convert ArrayList to Json, just download Open Source json utility from:
http://json.org/java/ or Jar file from here
And just do:
JSONArray jsonAraay = new JSONArray(your_array_list);
That's it
Note: You should have setter/getter in your POJO/MODEL class to convert arraylist to json
Don't bother with org.json, use Jackson all the way:
// list is a List<MyData>
final ObjectMapper mapper = new ObjectMapper();
final Map<String, MyData> map = new HashMap<>();
for (final MyData data: list)
map.put(data.fname, data);
final JsonNode json = mapper.valueToTree(map);
You could use all sorts of third party libraries like others here have suggested, or just use Play's own simplified methods for this (found in play.libs.Json) which works with Jackson objects, but it is integrated into the framework and requires a lot less code to use, for example:
JsonNode myJsonNode = Json.toJson(MyListObject); which converts the List to a JsonNode object, then use something like String jsonResult = Json.stringify(myJsonNode); to convert it into a string representation.
If you are using the JSON in a template, don't forget to wrap it in something like #Html(myJsonString) so it will not escape anything. Otherwise, if you are just outputting the pure JSON to the browser, a simple return ok(jsonResult); will work as Play will automatically set the content type.
Reference link: http://www.playframework.com/documentation/api/2.0/java/play/libs/Json.html
have you looked at this:
http://www.json.org/javadoc/org/json/JSONObject.html#valueToString(java.lang.Object)
JSONObject.valueToString(<<your list of custom object>> OR <<objects>> OR <<map>>)
works just fine...there are some other methods on that lib, if you are interested....

Sending JSON with arbitrary key values using REST service (Jersey/Jackson)

I want to send something like this from the client to the rest service
jsonObj =
{
"info" : {
"field1" : "val1"..
.....
"fieldN" : "valN"..
}
}
And I am not sure how can I handle this using a rest service using Jersey and Jackson in Java
I do not want to create a new info class with using Jackson properties with N field as they are going to change always. I just want to grab the jsonObject which is inside the jsonObject and operate on that as JsonObject.
Any thoughts ?
Assuming you have a root object that you are reading the result into, you could define docInfo as a Map<String, Object> within your jsonObj. This will probably work, but I can't give it a go presently.
If you don't have a root object you can just use a Map<String, Object> as your root object and play with it from there. That Map could contain other maps for nested json objects.
Yes, use a wrapper object with an embedded map, as #digitialjoel suggested. This is a concrete example:
class DocInfo {
private Map<String, Object> docInfo;
public DocInfo() {
super();
}
public DocInfo(final Map<String, Object> docInfo) {
super();
this.docInfo = docInfo;
}
// Getters, setters
}
final Map<String, Object> data = new LinkedHashMap<String, Object>(4);
data.put("field1", "value1");
data.put("field2", "value2");
data.put("field3", "value3");
data.put("field4", "value4");
final DocInfo info = new DocInfo(data);
final ObjectMapper mapper = new ObjectMapper();
final String json = mapper.writeValueAsString(info);
System.out.println(json);
Output:
{"docInfo":{"field1":"value1","field2":"value2","field3":"value3","field4":"value4"}}

serialize json object which extends map

Why this does not work?
public static class MyBean extends HashMap<String, String> {
public String city;
}
/**
* #param args
*/
public static void main(String[] args) {
MyBean bean = new MyBean();
bean.city = "some city";
Gson gson = new Gson();
String json = gson.toJson(bean);
System.out.println(json);
}
Why I dont see city value in json?
That's because instances implementing Map have special treatment by Gson. By default only its entry set will be serialized. You need to create a custom serializer which serializes both the entryset and the bean properties of interest separately.
E.g.
public class MyBeanSerializer implements JsonSerializer<MyBean> {
#Override
public JsonElement serialize(MyBean myBean, Type type, JsonSerializationContext context) {
JsonObject object = new JsonObject();
object.add("map", context.serialize(new HashMap<String, String>(myBean)));
object.add("city", context.serialize(myBean.city));
return object;
}
}
Which can be used as follows:
Gson gson = new GsonBuilder().registerTypeAdapter(MyBean.class, new MyBeanSerializer()).create();
String json = gson.toJson(bean);
System.out.println(json);
Update: hmm, as per the comment on the question (you should actually have posted it on the answer so that I will be notified immediately), the context.serialize(myBean.entrySet()) didn't seem to work out. And you're right, I just did a local test and I got the same exception. I tried adding a TypeToken on Set<Entry<String, String>>, but that ends up with an empty entryset somehow. Wrapping it in another map did work for me. I've updated the line in the answer.

Categories