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
Related
I am searching for this for quite some time now but still, it is not clear to me. I have a JSON file which looks like this:
{
"Name" : "Foo Bar",
"Grade" : "Some Grade",
"Org" : "Some Org"
}
For deserializing this JSON (using gson) I have created a Java class called StudentDetails.java which looks like this:
public class StudentDetails
{
public String name;
public String grade;
public String org;
}
Now I have a couple of questions regarding this:
Will gson automatically maps the fields in StudentDetails.java with corresponding keys even if the fields start with lower case and keys start from upper case in the JSON file. I have looked for #SerializedName but my code works without even using it. On the contrary if I am using something like #SerializedName("Name) with name field, it's getting assigned to null after deserialization. I am so confused right now.
Will deserialization work without even getter and setter methods? In jackson you write setter and getter methods.
If above is true, does it work even in the case of private fields?
I'm note sure about this one but i think the case only matters after the first character because you normally don't start the name of field with an upper-case character.
Yes GSON will automatically map the fields.
Yes GSON does not need getter/setter
(https://stackoverflow.com/a/6203975/4622620)
Yes GSON can handle private fields because it uses reflections (https://stackoverflow.com/a/28927525/4622620)
First of all I know that some other users have already asked a similar question before so you might think this is an duplicated question but it's not.
I want to make a model class to parse GoogleMaps-Direction API response from JSON format to java object.
The main goal is to make a custom request object using volley library so that I can consume the web service and having the response automatically converted into a Java object.
As you can see in the following screenshot the json response is formed by three root elements. The first two are arrays, at least, as far as I know the [] symbols are used to represent an array in JSON and the third one is just a string value.
So in the model class I'm trying to do the following, declaring some attributes to represent those elements in the JSON response.
Finally I created a new android studio project to test this application. You can see the code of the custom request as well.
However when I run the app I always get an exception that says:
I can understand the meaning of that message but I can't completely understand why this happens. The exception message points to the line number 16 in the response. I have tried using the JSONArray and JSONObject classes getting the same result
The thing is, GSON tries to find the geocodedWaypoints object in the JSON string and when it does, it tries to parse its value to an instance of JSONArray. But then again, JSONArray is an object itself and also expects an identifier. Hence, to use an array as a value, you ought to use the regular array type, e.g. String[].
Change the GoogleMapsResponse class to:
public class GoogleMapsResponse {
private GeocodedWaypoint[] geocodedWaypoints;
private Route[] routes;
private String status;
}
And create classes for all other objects:
public class GeocodedWaypoint {
private String geocoderStatus;
private boolean partialMatch;
private String placeId;
private String[] types;
}
etc.
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"
I have a java application which saves the fields of an object to a file and load them later again.
I used so far a modified version of java.util.properties.Properties file (the properties were written in the order they were put in the properties object). I defined for each field a property-key and use the following function to set the property in the properties object
properties.setProperty(PROPERTY_KEY_FIELD_X, field_x);
and used the following function if I want to read back from the properties file
field_x = properties.getProperty(PROPERTY_KEY_FIELD_X, ""));
where I can add a default value which will be choosed, when there is no property with the specified key. As I maybe add some fields in the future in the class from which the fields were saved in the file, I used this option with the default value to set a field to some defined value for the case I load a properties file which was written with an older version of this class.
So far it works but with some obvious disadvantage, for example I can't use the same property key more than once, I have to add some kind of indices like 1_PROPERTY_KEY, 2_PROPERTY_KEY. Thats why I came across JSON.
I'm not very familiar with JSON and all the things we can achieve with it. But I know I could use it to save the fields of an object to the JSON notation and read it back for example with Gson
//Object to JSON
Gson gson = new Gson();
String json = gson.toJson(object);
//JSON to Object
object = gson.fromJson(json);
But I assume this will fail, if the class is a newer version (i.e. some new fields) when try to read back from the JSON. How can I treat this? Do I have to take care of every seperate field similar to the the current implementation with properties? For example like this (with com.google.gson), assuming jsonString is the string read from the file:
//try/catch block omitted
JSONParser parser = new JSONParser();
JSONElement json = parser.parse(jsonString);
field_x = json.getAsString("field_x");
and take care if something failed to set default values to the fields?
Or is there a completely different approach without JSON or is JSON in general suitable for my use-case?
I'm not an expert of JSON too. But I used it sometimes with Jackson and I think Gson is very similar. If you want to use versioned objects just assure in your object constructor that fields are given with a default value (outside correct values range). Jackson will match only those json fields where it finds a correspondent filed in th Java object. Otherwise the default value is kept.
With GSON, you get to define your model as an object. As an example:
public class Configuration
{
private String x;
private String y;
}
Later, you may adjust Configuration to have an additional field, z:
public class Configuration
{
private String x;
private String y;
private String z;
}
When you use GSON to deserialise your JSON file that does not contain a value for z, it will be left null (or whatever the Java default value for that type is).
Since you have an object, you can define getters that substitute a default value if one is not specified:
public String getZ()
{
if (this.z == null)
{
return "the default z value";
}
return this.z;
}
If you're not goind to send data across network, I think you don't need Json but use native Java classes (ie properties). It's reduntant object creation
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.