Deserialize embeded Json fields objects into Java map - java

This is related to deserializing a JSON object with multiple items inside it .
I have the following Json object I need to deserialize in Java using Gson, and for the life of me, I'm pulling my hair out.
{
"Success":1,
"return":
{"MyObjects":
{"Obj1":
{"Prop1":"widgets", "Label":"Obj1", "prop2":"gadgets"}}
{"Obj2":
{"Prop1":"widgets2", "Label":"Obj2","prop2":"gadgets2"}}
{"Obj3":
{"Prop1":"widgets3", "Label":"Obj3","prop2":"gadgets3"}}
}
I have read and re-read the above linked question, and I am not quite understanding his solution.
I can make a MyJsonObject class as follows:
public class MyJasonObject{
private int success;
#SerializedName("return")
private isReturn isreturn;
}
The 'isReturn' class is where I'm lost. How should I parse the "MyObjects" into a map or a Json object? I didn't write the json string, it was handed to me... It looks like I could use a map for Myobject using the label field. But, I honestly don't know how to.

Related

Is there some way for a Jackson Delegate-based Creator to access the raw Json String?

Is there some way for a Jackson Delegate-based creator to access the raw Json String?
#JsonCreator
private static MyClass createFromJson(Map<String, Object> jsonProperties) {
return new MyClass(rawJson);
}
I am able to get the raw input as a Map of Strings to Objects in the code above, but I want to be able to access the json as a string. I tried the code below (based off of http://www.cowtowncoder.com/blog/archives/2011/07/entry_457.html) but that code as written is never invoked.
#JsonCreator
private static MyClass createFromJson(String rawJson) {
return new MyClass(rawJson);
}
Note: This is a spring boot application (1.3.1.RELEASE) that uses Jackson 2.6.4.
Looks like this type of functionality would not make sense in this context. In fact, it appears to me now that requesting the JSON string in this instance defeats the purpose of using jackson in the first place. However if anyone finds themselves here, then the comments from Sotirios Delimanolis may be useful:
"Hack: you can receive a JsonNode as the parameter type and use its toString method to get the corresponding JSON."
"It looks like you want a JsonDeserializer"

getting exact part of json

I have a json string, here is example
{
"Param1":"Value1",
"Param2":{...}
"ParamThatINeed":{...}
}
I want to get only "ParamThatINeed" object using gson lib in java, what is the best way to get what I need - write root class, then write class for "ParamThatINeed" and then decode json and use only "ParamThatINeed" object?
Or maybe it's better to beforehand convert my jsonString to another string, which will be only "ParamThatINeed" jsonString object using for example regexp? Or maybe there is a better way?
Your suggested solution is painless and extensible (i.e. if you decide to read an additional field in the future, you just add another field to your object). In general that's exactly how you want to use Gson - construct the necessary Java classes to represent the data you care about and Gson will silently discard the fields you don't care about. For your example that could look like:
private static final Gson GSON = ...;
public static class MyJsonData {
private final ParamThatINeed paramThatINeed;
public ParamThatINeed getParamThatINeed() { ... }
}
public static class ParamThatINeed {
...
}
public static ParamThatINeed extractParamThatINeed(String json) {
return GSON.fromJson(json, MyJsonData.class).getParamThatINeed();
}
You could parse the field yourself as #GuiSim suggests, but this won't scale as easily if your requirements change, and generally speaking the idea behind Gson is to avoid working directly with JsonElement and related classes.
I would definitely discourage a pre-processing step converting the JSON string into a different format. Structured data and string manipulations don't mix, as they lead to brittle code. JSON parsing libraries like Gson exist exactly to avoid such string manipulations.
JsonObject jobj = new Gson().fromJson(YOUR_JSON_HERE, JsonObject.class);
JsonElement value = jobj.get("ParamThatINeed");
value will contain the element associated with the ParamThatINeed key.

Map Dynamic json object to java

I am building a REST API with a payload that has a property called jsonContent, which holds any valid json.
{
"name":"foo",
"jsonContent":{ "abc":"My content"}
}
On the server side I want to map the it to a generic java object ,and eventually save the whole object to mongodb
private String name;
private ?????? jsonContent
I am using jackson for mapping json to java. How do I declare my java object so any json content can be used.
Use JsonNode:
private JsonNode jsonContent;
I answer my own question, Following worked just fine for me
private Map<String,Object> jsonContent;

How to serialize JSON Array into Java HasMap, using specific field as a key with GSON?

For example, given JSON:
[
{"id":"3", "location":"NewYork", "date":"yesterday"},
{"id":"4", "location":"Moscow", "date":"today"}
]
resulting HashMap:
<"3", POJOLocation("NewYork", "yesterday")>
<"4", POJOLocation("Moscow", "today")>
where POJOLocation is a Java object:
class POJOLocation {
private String location;
private String date;
// etc
}
I've tried using custom deserializer, but it was really bloated with generic's tokens and hackish typeOfs. Perhaps there is a simple efficient solution?
Maybe create a POJOLocationId class:
class POJOLocationId {
private int id;
private String location;
private String date;
// etc
}
Then deserialize & loop over the resulting List populating your HashMap as you go?
Gson is designed to make serializing Java objects to their JSON equivalent painless. If you're trying to represent a Java data structure as a different type of JSON structure you're not going to have a lot of fun writing serializers and deserializers. At that point you might consider a lower-level JSON parser and simply implement the parsing you want yourself. Rather than representing your data one way in JSON and another way in Java (and thus running into the hassle of transforming between them) you might consider refactoring either your data structure or your data so they're more similar.
That said the easiest thing to do with Gson (which is really not that bad, memory and time-wise) is to use a wrapper type and then transform the input/output before using it. Something like so (borrowing from Tom Mac's type name):
private static final Type LIST_TYPE =
new TypeToken<List<POJOLocationId>>() {}.getType();
public String serialize(Map<Integer, POJOLocation> locations) {
List<POJOLocationId> locationsList = original.entrySet().stream()
.map(e -> new POJOLocationId(e.getKey(), e.getValue()).collect(toList());
return gson.toJson(locationsList);
}
public Map<Integer, POJOLocation> deserialize(String json) {
List<POJOLocationId> locationsList = gson.fromJson(json, LIST_TYPE);
return locationsList.stream()
.collect(toMap(l -> l.getId(), new POJOLocation(l)));
}
You certainly can get this same behavior with a custom deserializer, but this works, it's clean, and it's easy to read. The garbage collector should have no trouble cleaning up these temporary wrappers as soon as these methods return.

Is case important while parsing JSON using GSON

I am parsing JSON data, and storing the results in a Java object using GSON. My question is, should the fields in the JSON String match the instance variables in the class? Including the class names? For eg,
If this is my JSON string -
"telephone":
{
"landline":"1-818-502 8310"
}
Should I have a class as below?
public class Telephone
{
private String landline;
}
The reason why I am asking this is, when I use gson's fromJson(obj), the object doesn't contain any values. It shows all records as null. I am wondering if it is throwing the error due to this.
Please note - This is not the entire code. My JSON data is quite huge, so I can't paste it here. The above telephone string is just one of the many embedded strings within my json string.
This is wrong JSON:
"telephone":{"landline":"1-818-502 8310"}
The JSON objects start with a { and end with a }. SO, it should be something like
{"name": "somename", "telephone":{"landline":"1-818-502 8310"}, ...}
Yes. Attributes in class should have exact same case and character as in the JSON String in case you are using default Gson instance as correctly mentioned by Eliran. Please note that you must have attributes just having getter/setter and not attribute wouldn't work.
You mentioned you are using inner class. It may not work with default Gson instance. You may need to use registerTypeAdapter like this:
gson.registerTypeAdapter(MyType.class, new MyInstanceCreator());
refer: https://sites.google.com/site/gson/gson-user-guide#TOC-Custom-Serialization-and-Deserialization

Categories