I am in need to convert nested JSON to Java Object which is an Interface.
Kindly refer the below example,that JSON string needs to convert into Java Object of type Root.
JSON: {"ROOT":{"NAME":"EVEN"}}
Java:
Interface Root {
String getName();
}
class RootImpl implements Root{
private String name;
public String getName() {
return name;
}
}
Like the below usecase i need to convert nested json of large depth to Java Object.
you can do it with:-
JSONSerializer.toJava(jsonString);
You can use the org.json. Java parser.
public class RootImpl implements Root{
private JSONObject root;
public RootImpl(String json) {
this.root = new JSONObject(json).getJSONObject("ROOT");
}
public String getName(){
return root.getString("NAME");
}
}
Root root = new RootImpl("{\"ROOT\":{\"NAME\":\"EVEN\"}}");
System.out.println(root.getName()); // prints: EVEN
References:
JSON Java API docs
The Google GSON can help you !
"Gson is a Java library that can be used to convert a Java object into its
JSON representation. It can also be used to convert a JSON string into an
equivalent Java object. Gson can work with arbitrary Java objects including
pre-existing objects that you do not have source-code of." --Google-Gson 'README'
Download url:
https://code.google.com/p/google-gson/downloads/list
code example:
//UserInfo object to json string
public String toJson(UserInfo userInfo){
//com.google.gson.Gson
return new Gson().toJson(userInfo);
}
//json string to UserInfo object
public UserInfo fromJson(String jsonStr){
return new Gson().fromJson(jsonStr, UserInfo.class);
}
Related
I am trying to make a java program that will need to work with json, I have choose gson as my library to handle managing JSON
But when I try to deserialize my json the messagereturn.text value and the messagereturn.extra.text value both get set as null, I have tried to fix this but I am unable to.
An example of the json that i am trying to deserialize is
{
"text":"",
"extra":[{
"text":"eee joined the game",
"color":"yellow"
}]
}
And this is how I am calling gson
Message messagepacket = event.<ServerChatPacket>getPacket().getMessage();
//this gets the json data
messagereturn messagereturn = gson.fromJson(String.valueOf(messagepacket), messagereturn.class);
System.out.println(messagereturn.returnmethod());
Here is the class I am trying to deserialize too
public class messagereturn {
String text;
public class extra{
String text;
}
public String returnmethod() {
extra extra = new extra();
return text + extra.text;
}
}
Thank you, if there is any more informaton needed let me know, thanks
There is a problem understanding your JSON (and creating the Java classes by the way). These marks [] means that is a list.
So you have an object with atributes text, type String and extra, type List<Object>.
This list contains another object (note that the object is defined by {} and list by []).
The object into the list has another two attributes: text and color both with primitive types; String.
So your java class should be like this:
public class Messagereturn {
private String text;
private List<Extra> extra;
//getters and setters and other methods
}
And the class Extra:
public class Extra {
private String text;
private String color;
//getters and setters
}
With this data model you can call your Gson with these structure.
Also, you don't need to call returnMethod to create Extra object, it is created by Gson.
Using this line of code:
Messagereturn mr = new Gson().fromJson(txt, Messagereturn.class);
And your JSON example, this is the value stored when run in debug mode:
As you can see, tha values from JSON has been created and loaded into memory.
This is an example of the kind JSON I'm trying to consume using GSON:
{
"person": {
"name": "Philip"
"father.name": "Yancy"
}
}
I was wondering if it were possible to deserialize this JSON into the following structure:
public class Person
{
private String name;
private Father father;
}
public class Father
{
private String name;
}
So that:
p.name == "Philip"
p.father.name == "Yancy"
Currently I am using #SerializedName to obtain property names containing a period, e.g.:
public class Person
{
private String name;
#SerializedName("father.name")
private String fathersName;
}
However, that's not ideal.
From looking at the documentation it doesn't appear to be immediately possible but there may be something I have missed - I'm new to using GSON.
Unfortunately I cannot change the JSON I'm consuming and I'm reluctant to switch to another JSON parsing library.
As far as I understand you can't do it in a direct way, because Gson will understand father.name as a single field.
You need to write your own Custom Deserializer. See Gson user's guide instructions here.
I've never tried it, but it doesn't seem to be too difficult. This post could be also helpful.
Taking a look at Gson's user guide and the code in that post, you'll need something like this:
private class PersonDeserializer implements JsonDeserializer<Person> {
#Override
public Person deserialize(JsonElement json, Type type,
JsonDeserializationContext context) throws JsonParseException {
JsonObject jobject = (JsonObject) json;
Father father = new Father(jobject.get("father.name").getAsString());
return new Person(jobject.get("name").getAsString(), father);
}
}
Assuming that you have suitable constructors...
And then:
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Person.class, new PersonDeserializer());
Gson gson = gsonBuilder.create();
Person person = gson.fromJson(jsonString, Person.class);
And Gson will call your deserializer in order to deserialize the JSON into a Person object.
Note: I didn't try this code, but it should be like this or something very similar.
I couldn't do this with just Gson. I need a new library 'JsonPath'. I used Jackson's ObjectMapper to convert the object to string but you can easily use Gson for this.
public static String getProperty(Object obj, String prop) {
try {
return JsonPath.read(new ObjectMapper().writeValueAsString(obj), prop).toString();
} catch (JsonProcessingException|PathNotFoundException ex) {
return "";
}
}
// 2 dependencies needed:
// https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
// https://mvnrepository.com/artifact/com.jayway.jsonpath/json-path
// usage:
String motherName = getProperty(new Person(), "family.mother.name");
// The Jackson can be easily replaced with Gson:
new Gson().toJson(obj)
Using Gson, I'm trying to de-serialize a a nested, generic class. The class structure looks like the following:
Wrapper object, simplified, but normally holds other properties such as statusMessage, which are returned along with the data-field from the server:
public class Response<T> {
private List<T> data = null;
public List<T> getData() { return this.data; }
}
Simple class, the expected output from data-field above (though as an array):
public class Language {
public String alias;
public String label;
}
Usage:
Type type = new TypeToken<Response<Language>>() {}.getType();
Response<Language> response = new Gson().fromJson(json, type);
List<Language> languages = response.getData();
Language l = languages.get(0);
System.out.println(l.alias); // Error occurs here
Where the json-variable is something like this.
However, when doing this, I recieve the following exception (on line 3, last code example):
ClassCastException: com.google.gson.internal.StringMap cannot be cast to book.Language
The exception ONLY occurs when storing the data from getData() into a variable (or when used as one).
Any help would be highly appreciated.
The problem you're actually having is not directly due to Gson, it's because of how arrays and Generics play together.
You'll find that you can't actually do new T[10] in a class like yours. see: How to create a generic array in Java?
You basically have two options:
Write a custom deserializer and construct the T[] array there as shown in the SO question I linked above
Use a List<T> instead, then it will simply work. If you really need to return an array, you can always just call List.toArray() in your method.
Edited from comments below:
This is a fully working example:
public class App
{
public static void main( String[] args )
{
String json = "{\"data\": [{\"alias\": \"be\",\"label\": \"vitryska\"},{\"alias\": \"vi\",\"label\": \"vietnamesiska\"},{\"alias\": \"hu\",\"label\": \"ungerska\"},{\"alias\": \"uk\",\"label\": \"ukrainska\"}]}";
Type type = new TypeToken<Response<Language>>(){}.getType();
Response<Language> resp = new Gson().fromJson(json, type);
Language l = resp.getData().get(0);
System.out.println(l.alias);
}
}
class Response<T> {
private List<T> data = null;
public List<T> getData() { return this.data; }
}
class Language {
public String alias;
public String label;
}
Output:
be
I'm using Gson 2.2's toJson() method to serialize a java object into a json string. The java object is of type:
public class LOB implements Serializable{
private int id;
private LOBType type;
private TypeSpecificData data;
public class TypeSpecificData {
private String a;
private int b;
}
}
All fields of the object are serialized except for data field of type TypeSpecificData.
How do I include this field as well in the json string ?
Currently I'm serializing like shown below:
String jsonString = new Gson().toJson(lob_instance);
By default Gson will not serialize null objects refereces. Please check it.
Link to GSON documentation
Let's imagine I have a Java class of the type:
public class MyClass
{
public String par1;
public Object par2;
}
Then I have this:
String json = "{"par1":"val1","par2":{"subpar1":"subval1"}}";
Gson gson = new GsonBuilder.create();
MyClass mClass = gson.fromJson(json, MyClass.class);
The par2 JSON is given to me from some other application and I don't ever know what are it's parameter names, since they are dynamic.
My question is, what Class type should par2 variable on MyClass be set to, so that the JSON String variable is correctly deserialized to my class object?
Thanks
Check out Serializing and Deserializing Generic Types from GSON User Guide:
public class MyClass<T>
{
public String par1;
public T par2;
}
To deserialize it:
Type fooType = new TypeToken<Myclass<Foo>>() {}.getType();
gson.fromJson(json, fooType);
Hope this help.
See the answer from Kevin Dolan on this SO question: How can I convert JSON to a HashMap using Gson?
Note, it isn't the accepted answer and you'll probably have to modify it a bit. But it's pretty awesome.
Alternatively, ditch the type safety of your top-level object and just use hashmaps and arrays all the way down. Less modification to Dolan's code that way.
if you object has dynamic name inside lets say this one:
{
"Includes": {
"Products": {
"blablabla": {
"CategoryId": "this is category id",
"Description": "this is description",
...
}
you can serialize it with:
MyFunnyObject data = new Gson().fromJson(jsonString, MyFunnyObject.class);
#Getter
#Setter
class MyFunnyObject {
Includes Includes;
class Includes {
Map<String, Products> Products;
class Products {
String CategoryId;
String Description;
}
}
}
later you can access it:
data.getIncludes().get("blablabla").getCategoryId()
this code:
Gson gson = new GsonBuilder.create();
should be:
Gson gson=new Gson()
i think(if you are parsing a json doc).