i have class like this
public class Response<T>{
T item;
List<T>;
}
so how can to deserializeding String in this pattern to one generic class withgson.fromJson(targetString,...)?
i glad to used in retrofit library where Response is returned parameter in desired interface
convert list to gson
public <T> String setList(List<T> list) {
Gson gson = new Gson();
return gson.toJson(list);
}
convert gson to list
public List<(desired class)> getList(){
Gson gson = new Gson();
String json = (pass json string);
Type type = new TypeToken<List<(desired class)>>() {}.getType();
return gson.fromJson(json, type);
}
Add gson dependency to the app gradle file.
implementation 'com.google.code.gson:gson:2.8.6'
Related
I want to convert a list of a model that I've defined to String for saving it in Database I know how to do that in Gson but I want to do the same in kotlinx.serialization
Convert a list of a model to String In Gson:
val gson = Gson()
return gson.toJson(data)
Convert the String to the model in Gson:
val listType = object : TypeToken<ArrayList<String>>() {}.type
return Gson().fromJson(string, listType)
How can I do that in kotlinx.serialization?
I don't even know if this is a valid question but I am having a hard time converting the API result to POJO since some key are dynamic.
{
"data": [{
"something_edit": true
},
{
"test_null": false
}
],
"success": true
}
As you can see the key inside data are dynamic. I tried using jsonschema2pojo or other converter but it is declaring a named variable which is not a good result. BTW I am using retrofit and GSON library
EDIT:
So here is the flow, so the keys are the ones I asked on the API. So for Example I asked something_edit1, something_edit2 and something_edit3. The data result will be.
{
"data": [{
"something_edit1": true
}, {
"something_edit2": false
},
{
"something_edit3": false
}
],
"success": true
}
You can use Json Object or Generics for your condition.
Using Json Object you can check, if key is exist in your json.
if(yourJsonObject.hasOwnProperty('key_name')){
// do your work here
}
Using Generic you have to check, if your Pojo have instance of the
Pojo.
if(YourMainPOJO instanceOf YourChildPojo){
// do your work here
}
Try to view only Generic part in this link.
It's hard to determine or you have to declare all the possible fields in your POJO or write your own json parser extending the Gson Parser or use a JsonElement which can be converted into json array, object and primitive, based on that result you can convert back to some specific pojo.
/**
* this will convert the whole json into map which you can use to determine the json elements
*
* #param json
*/
private void getModelFromJson(JsonObject json) {
Gson gson = new Gson();
Map<String, JsonElement> jsonElementMap = gson.fromJson(json.toString(), new TypeToken<Map<String, JsonElement>>() {
}.getType());
for (Map.Entry<String, JsonElement> jsonElementEntry : jsonElementMap.entrySet()) {
if (jsonElementEntry.getValue().isJsonPrimitive()) {
//json primitives are data types, do something
//get json boolean
//you can here also check if json element has some json object or json array or primitives based on that
//you can convert this to something else after comparison
if (true) {
InterestModelResponse response = gson.fromJson(jsonElementEntry.getValue().getAsJsonObject().toString(), InterestModelResponse.class);
//use your dynamic converted model
}
} else {
//do something else
}
}
}
2 Years ago we did a project in which we had to handle notifications data with different type of objects in same array we handle that while using retrofit
this is our retrofit Creator class
class Creator {
public static FullTeamService newFullTeamService() {
final HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
final OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.build();
final Retrofit retrofit = new Retrofit.Builder()
.baseUrl(FullTeamService.HOST)
.client(client)
.addConverterFactory(GsonConverterFactory.create(GsonUtils.get()))
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
return retrofit.create(FullTeamService.class);
}
}
and GsonUtils.java is:
public class GsonUtils {
private static final Gson sGson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss")
.registerTypeAdapter(NotificationObject.class, new NotificationDeserializer())
.create();
private GsonUtils() {}
public static Gson get() {
return sGson;
}
}
NotificationObject is something like:
public class NotificationObject {
#SerializedName("ID")
#Expose
private long ID;
#SerializedName("type")
#Expose
private Type type;
#SerializedName("DataObject")
#Expose
private NotificationDataObject dataObject;
public void setDataObject(NotificationDataObject newsFields) {
dataObject = newsFields;
}
#SuppressWarnings("unchecked")
public <T> T getDataObject() {
return (T) dataObject;
}
public enum Type {
#SerializedName("0")
CHAT_MESSAGE,
#SerializedName("10")
GAME_APPLICATION,
#SerializedName("20")
GAME_APPLICATION_RESPONSE,
#SerializedName("30")
GAME_INVITE....
}
}
NotificationDataObject as new class is like:
public class NotificationDataObject {}
and finally NotificationDeserializer is like:
public class NotificationDeserializer implements JsonDeserializer<NotificationObject> {
#Override
public NotificationObject deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
final JsonObject itemBean = json.getAsJsonObject();
final NotificationObject object = GsonUtils.getSimpleGson().fromJson(itemBean, NotificationObject.class);
switch (object.getType()) {
case CHAT_MESSAGE:
break;
case GAME_APPLICATION:
object.setDataObject(GsonUtils.get().fromJson(itemBean.get("DataObject").getAsJsonObject(),
GameApplicationNotification.class));
break;
case GAME_APPLICATION_RESPONSE:
object.setDataObject(GsonUtils.get().fromJson(itemBean.get("DataObject").getAsJsonObject(),
GameApplicationResponseNotification.class));
break;
case GAME_INVITE:
object.setDataObject(GsonUtils.get().fromJson(itemBean.get("DataObject").getAsJsonObject(),
GameInviteNotification.class));
break;
}
return object;
}
}
Happy coding ...!
any query will be appreciated...
class Response<T>(
JHeader header;
T result;
)
class JHeader(
Int success;
List<String> error;
)
class Character{
#SerializedName("id_") Int id;
#SerializedName("levelA") String level
#SerializedName("a3") unit: String = "
Character(Int id, String level) {
this.id = id
this.level= level
}
}
Retrofit.Builder()
.addCallAdapterFactory(rxAdapter)
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(BASE_URL)
.client(httpClient.build())
.build()
public Observable<Response<List<Character>>> getCharacterById(characterID: Int){
return apiService.getCharacter(characterID)
.subscribeOn(Schedulers.io())
}
And i have a custom type adapter made for Character.
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Character.class, new CharacterTypeAdapter());
Gson gson = gsonBuilder.create();
Gson is completly ignoring my type adapter while deserializing the list so i guess because of generic type erasure, the List gets treated like a List Object or something, so my adapter wont be used.
Using Retrofit2. Is there any way i can do his with generics, without having to create custom classes for Lists every time i need to parse a response which contains a list?
I need to create the following JSON Object and than convert it to string using the GSON library (toJson(Object)). However, GSON appends the nameValuePair with each JSON Object, what do I need to do?
"Param_1":
{
"SubParam_1": { type: String, required: true }
}
I'm putting these JSONObjects into a ParameterMap (android HTTP Client) and using GSON to convert the map to JSON String.
First of all the JSON "object" you've written is not even valid JSON!
If anything, you could create a JSON like this:
{
"Param_1": {
"SubParam_1": { "type": "String", "required": true }
}
}
And that's very easy, you just need to have the correct class model, something like this:
public class YourClass {
private Param Param_1;
}
public class Param {
private SubParam SubParam_1;
}
public class SubParam {
private String type;
private boolean required;
}
And then you can use the method .toJson(), like this:
Gson gson = new Gson();
String jsonString = gson.toJson(yourObject);
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.