I am using retrofit w/ gson annotations to bind my incoming JSON to a model and its member attributes to types like String, int, float, etc...
public class Location {
#SerializedName("user_id")
#Expose
private int userId;
But how do I bind to a member variable that's of type JSON? I want it to be unstructured which is why I can't just map it to a well-defined model.
#SerializedName("metadata")
#Expose
private JsonObject metadata;
How do I get the above to work?
Looks like I can set the member attribute to JsonElement
#SerializedName("metadata")
#Expose
private JsonElement metadata;
This resolves the issue of binding to JsonNull + JsonObject.
Related
I have an BaseResponse<T>
public class BaseResponse<T> {
#SerializedName("status")
private int status;
#SerializedName("data")
private T data;
which is the reponse from Http request.The <T> can be both object or list.But if there's an error ,server make a mistake which return a List even if the response (if success) return an object like this.
{"status":116,"data":["Data is invalid"]}
So my question : Is there anyway to get the datatype inside Callback<BaseResponse<T> from Interceptor
so I can change the data to and String Object.
Or else,is there anyway to solve my problem?
I am using Retrofit to get the data from the API and parse it into a POJO object.
However, the API is not documented and I am not very sure what data does the JSON contain.
I have field in my POJO for the data I am sure is coming, but at times they are fields in the JSON that I have not accounted for.
Obviously, Retrofit just ignores these fields.
How can I make it send a warning when a field in the JSON is NOT in the POJO?
class User {
#SerializedName("id")
private Integer id;
#SerializedName("name")
private String name;
[relevant getters and setters]
}
The JSON that is coming is:
{
id: 5,
name: "John",
age: 23
}
Age field is not in the POJO, but at application does not throw any error; how do I make it display an error in such instances?
You may consider using Jackson to deserialize your POJO.
Then you can use the following annotations:
#JsonIgnoreProperties(ignoreUnknown = false)
i need to send #Body like next:
{
"test": "test",
"test2": {
"test2": "test2",
"test2": "test2",
},
"test3": {
"test3": "test3",
"test3": "test3",
},
}
I am new with retrofit, I know how to create simple #Body object, but how create objects inside object - I have no idea.
will be glad any help!
Just create classes for these inner objects, and aggregate them into one object:
class TestWrapper {
#Expose
String test;
#Expose
Test2 test2;
#Expose
Test3 test3;
}
class Test2 {
#SerializedName("something_name") // <- this will be the JSON key name
#Expose
String something;
#SerializedName("something_else_name")
#Expose
String somethingElse;
}
etc.
Then pass the TestWrapper object as the request #Body.
Also, not that in your JSON you named two objects the same ("test2", "test3") - you can't do it, keys must be unique.
Annotations in this code are the GSON library annotations:
#Expose and
#SerializedName
I'm working on API Requests with Retrofit(1.9.0) and gson library (1.7.0 I have compatibility issues with version 2.3.1 of gson) on Android, I make some request to an API which have same format of response but different content following the url call, but I encounter a problem for a deserialization of one answer which there is array inside. This is an example of the json I want to deserialize :
{
"http_code":200,
"content":[
{
"name":"Groult Christian",
"location":[
48.897655,
2.252462
],
"website":null,
"address":{
"street_address":"XXXXXX",
"city":"XXXXXX",
"state":null,
"postal_code":"XXXXXX",
"country":"XXXXXX"
},
"global_score":0,
"popularity_score":0,
"quality_score":0,
"createdAt":"2015-02-18T02:13:05.068Z",
"updatedAt":"2015-02-18T02:13:05.068Z",
"id":"54e3f531775288ca572872ac"
},
...
]
}
My DeserializerJson and how I call it for retrofit:
public class DeserializerJson<T> implements JsonDeserializer<T> {
#Override
public T deserialize(JsonElement je, Type type, JsonDeserializationContext jdc)
throws JsonParseException
{
// Get the "content" element from the parsed JSON
JsonElement content = je.getAsJsonObject().get("content");
// Deserialize it. You use a new instance of Gson to avoid infinite recursion
// to this deserializer
return new Gson().fromJson(content, type);
}
}
...
Gson gson = new GsonBuilder()
.registerTypeAdapter(ContentUser.class, new DeserializerJson<ContentUser>())
.registerTypeAdapter(DeviceInfo.class, new DeserializerJson<DeviceInfo>())
.registerTypeAdapter(PlacesModel.class, new DeserializerJson<PlacesModel>())
.create();
RestAdapter restAdapter = new RestAdapter.Builder()
.setLogLevel(RestAdapter.LogLevel.BASIC)
.setConverter(new GsonConverter(gson))
...
...
and my different models:
public class PlacesModel {
#SerializedName("name")
#Expose
private String name;
#SerializedName("location")
#Expose
private List<Double> location = new ArrayList<Double>();
#SerializedName("website")
#Expose
private Object website;
#SerializedName("address")
#Expose
private AddressModel address;
#SerializedName("global_score")
#Expose
private Integer globalScore;
#SerializedName("popularity_score")
#Expose
private Integer popularityScore;
#SerializedName("quality_score")
#Expose
private Integer qualityScore;
#SerializedName("createdAt")
#Expose
private String createdAt;
#SerializedName("updatedAt")
#Expose
private String updatedAt;
#Expose
#SerializedName("id")
private String id;
/* Getters and Setters... */
}
public class AddressModel {
#SerializedName("street_address")
#Expose
private String streetAddress;
#SerializedName("city")
#Expose
private String city;
#SerializedName("state")
#Expose
private Object state;
#SerializedName("postal_code")
private String postalCode;
#SerializedName("country")
#Expose
private String country;
/* Getters and Setters... */
}
url call in Api Manager is like this:
#GET("/places")
public void getPlaces(RestCallback<List<PlacesModel>> callback);
But when I do the call I get this error : com.google.gson.JsonParseException: The JsonDeserializer com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter#3b8aa06 failed to deserialize json object
Everything is fine for other call I get all content and so with no problem but one where there is array inside content I got an error and I don't understand why I believed if I just put a list of my model it will be fine but it doesn't work.
I think I miss something so if someone can help me
Thanks in advance
The problem of your issue is that you register DeserializerJson for PlacesModel class and in getPlaces method your response is List<PlacesModel> class. List<PlacesModel> is a different class as PlacesModelso Gson doesn't know how to deserialise List<PlacesModel>. What you have to do is register one more Deserialiser by this method:
.registerTypeAdapter(List.class, new DeserializerJson<List<PlacesModel>>())
If you use more than one type of List (I mean List<PlacesModel> and List< DeviceInfo >) You can define your own TypeAdapter or you cN change list to array and register deserialiser for them as is shown below
.registerTypeAdapter(PlacesModel[].class, new DeserializerJson<PlacesModel[]>())
Now everything works fine for yours json.
I am trying to serialize/deserialize JSON in Android using GSON. I have two classes that look like this:
public class Session {
#SerializedName("name")
private String _name;
#SerializedName("users")
private ArrayList<User> _users = new ArrayList<User>();
}
and:
public class User {
#SerializedName("name")
private String _name;
#SerializedName("role")
private int _role;
}
I am using GSON for serializing/deserializing the data. I serialize like so:
Gson gson = new Gson();
String sessionJson = gson.toJson(session);
This will produce JSON that looks like this:
{
"name":"hi",
"users":
[{"name":"John","role":2}]
}
And I deserialize like so:
Gson gson = new Gson();
Session session = gson.fromJson(jsonString, Session.class);
I'm getting an error when I make this call.
DEBUG/dalvikvm(739): wrong object type: Ljava/util/LinkedList; Ljava/util/ArrayList;
WARN/System.err(739): java.lang.IllegalArgumentException: invalid value for field
I don't know what this error means. I don't see myself doing anything gravely wrong. Any help? Thanks!
Change your code to this:
public class Session {
#SerializedName("name")
private String _name;
#SerializedName("users")
private List<User> _users = new ArrayList<User>();
}
It's a good practice use Interfaces, and GSON requires that (at least, without extra configuration).
Gson converts the array "[ ]" in javascript, to a LinkedList object.
In your code, GSON tries to inject a LinkedList in the _users field, thinking than that field its a List.