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.
Related
After multiple researches on Google and Stack Overflow, i haven't found a similar case to mine.
I need to use Gson library to convert a Java object to Json. The fact is that this object contains a field with a custom generic type, as follow :
SendData.java :
public class SendData {
private SendDataRequestObject<?> sendData;
// Constructor + Getters and Setters
}
Here is the class definition of SendDataRequestObject :
public class SendDataRequestObject<T> {
private String actionType;
private T parameters;
private CustomClass customClass;
//Constructor + Getters and Setters
}
And finally, the class definition of MyRequest which may be injected in SendDataRequestObject as the T parameter
public class MyRequest {
private Map<Integer, String> myMap;
private String myString1;
private String myString2;
//Constructor + Getters and Setters
}
Actually, I'm able to parse SendDataRequestObject with Gson library as follow :
SendDataRequestObject<MyRequest> requestObject = new SendDataRequestObject<MyRequest>();
//...
//Initializing and adding fields to requestObject
//...
Type token = new TypeToken<SendDataRequestObject<MyRequest>>(){}.getType();
System.out.println(new GsonBuilder().create().toJson(requestObject, token));
The output is properly set and every fields, even the generic one, are included into the final json string :
{"actionType":"verify","parameters":{"myMap":{"15789":"hreher-489hre-gdsf","13057":"rtyuiop-4g8ezg","16741":"gfd456-uiop789"},"myString1":"myStringValue1","myString2":"myStringValue2"},"customClas":{"attr1":"value1","attr2":"value2"}}
But what I need is to parse SendData class, not SendDataRequestObject class. When I try to convert this class into json string, I obtain this output :
{"sendData":{"actionType":"verify","parameters":{},"customClass":{"attr1":"value1","attr2":"value2"}}}
So, we can see that parameters field of SendDataRequestObject is not converted to Json, probably because this is a generic class.
If anybody has an idea of how to do it, I would be very grateful !
You can't do this without somehow knowing the type T at compile time in some manner due to Java's type erasure.
One option for this is the JSON can contain some information specifying the type, e.g.
{
"sendDataType": "MyRequest",
"sendData": {
...
}
}
If you then make SendData generic e.g.
SendData<T> {
private SendDataRequestObject<T> sendData;
}
you can then parse the JSON once to find out the sendDataType:
SendData<?> genericSendData = new GsonBuilder().create().toJson(requestObject, new TypeToken<SendData<?>>(){});
String sendDataType = genericSendData.sendDataType;
and use that to create a TypeToken of the right type:
switch(sendDataType) {
case "MyRequest":
return new TypeToken<MyRequest>(){};
}
And then parse the JSON again specifying the generic type now that you know it:
SendData<?> myRequestSendData = new GsonBuilder().create().toJson(requestObject, typeToken);
This works because our switch statement knows the possible types at compile time and can create TypeTokens for them.
I'm using a method that takes a Class<T> as a parameter.
The class I want to pass as a parameter also uses T. It is declared as public class MyObject<T> and has a member declared as public T mMyVar; I then have 2 classes I sometimes use for mMyVar called MyVarObject1 and MyVarObject2.
Example:
private class MyObject<T> {
public T mMyVar;
}
private class MyVarObject1 {
// some variables
}
private class MyVarObject2 {
// some variables
}
Specifically, the method I'm invoking is the JacksonUtil method fromJsonArray.
I'm not sure of the proper syntax here. JacksonUtil needs to know the exact model structure so it can parse the json, but I'm having trouble figuring out the proper syntax for this line:
MyObject<MyVarObject1> result = JacksonUtil.fromJsonArray(jsonStr, MyObject<MyVarObject1>.class);
What I have there doesn't work. My IDE selects the second parameter and says, "Cannot select from parameterized type."
I had a same problem while using with retrofit, This is my solution -
public class ResponseDS<T> {
public int s;
public String e;
public T d;
}
And if you need array of object then,
public class ResponseDSs<T> {
public int s;
public String e;
public T[] d;
}
And below is how I am using it for Retrofit -
Call<ResponseDS<UserDS>> userModelCall = ZivaUtils.getRetrofit().getUser();
I think you have the same problem, hope my solution will help you :)
I do TypedToken from Gson to parse custom objects, I think you can find something similar to use with Jackson, i will edit my answer if i find something later.
You may use TypeToken to load the json string into a custom object.
Gson gson = new Gson();
//This is an example, you probably get this from your server as Json String
MyObject<MyObject1> user = new MyObject<MyObject1>();
String myObjectAsString = gson.toJson(user);
//then parse into your custom object
MyObject other = gson.fromJson(myObjectAsString, new TypeToken<MyObject<MyObject1>>(){}.getType());
I have a json object like this:
{
products:[
{
name:Prod1,
quantity:3
},
{
name:Prod2,
quantity:1
}
]
}
I have my gson object like so:
public class Product{
#SerializedName("name")
public String name;
#SerializedName("quantity")
public int quantity;
}
When I set up my retrofit with something like this
#GET("/products")
void getProducts(Callback<ArrayList<Product>> c);
It will fail, obviously, because that array isn't the root object. Is there a simple way to force this to dig down into the json one level before parsing that ArrayList, or am I going to have to create a whole GSON adapter to accomplish this?
I accomplished this by creating and using my own custom deserializer. The code is simpler than a full Gson Adapter, but accomplishes what I need.
https://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/JsonDeserializer.html
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);
}
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