Skip level when parse with Gson

*爱你&永不变心* 提交于 2020-01-10 04:16:04

问题


I have some json format look like:

{
"root": {
    "user": {
        "name":"Name",
        "age":99,
        "another_obj": {
            "f1":"abc",
            "f2":1
        }
    }
},
"result_code": 0
}

I create some model look like:

class User {
private String name;
private int age;
@SerializedName("detail")
private Detail
}

class Detail{
   // Define something.
}

finally I create class name UserWapper.

class UserWapper {
@SerializedName("root")
private User user;  
}

To parse json:

String json = "STRING_JSON_ABOVE";
Gson gson = new Gson();
UserWrapper uw = gson.fromJson(json, UserWrapper.class);

But current I don't want create class Wrapper. Because I have many many class. If create WrapperClass -> :|

I want to do something like:

User u = gson.fromJson(json, User.class).

(Note: I can't change format data json from server. I also gg search something custom gson adapter but I don't find a way for skip "level" another field).


回答1:


If you don't want a wrapper class, you can parse your json string to a JsonObject, then get its user object, and deserialize the user object to an instance of your User class.

Try below code:

String json = "{\"root\":{\"user\":{\"name\":\"Name\",\"age\":99,\"another_obj\":{\"f1\":\"abc\",\"f2\":1}}},\"result_code\":0}";
Gson gson = new Gson();
JsonObject jsonObject = gson.fromJson(json, JsonObject.class);
User u = gson.fromJson(((JsonObject)jsonObject.get("root")).get("user"), User.class);

System.out.println("user.name: " + u.name);
System.out.println("user.age: " + u.age);

Output:

user.name: Name
user.age: 99




回答2:


I just implemented another approach: annotate a JsonAdapter on the field that contains just a wrapper object. The JsonAdapter is actually a TypeAdapterFactory, like this:

/**
 * Use with {@link com.google.gson.annotations.JsonAdapter} on fields to skip a single pseudo object
 * for map-like types.
 */
public class UnwrappingJsonAdapter implements TypeAdapterFactory {

    @Override
    public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> type) {
        return new TypeAdapter<T>() {

            @Override
            public void write(JsonWriter out, T value) throws IOException {
                out.beginObject();
                out.name(type.getType().getClass().getSimpleName());
                gson.toJson(value, type.getType(), out);
                out.endObject();
            }

            @Override
            public T read(JsonReader in) throws IOException {
                in.beginObject();
                in.nextName();
                final T object = gson.fromJson(in, type.getType());
                in.endObject();
                return object;
            }
        };
    }
}

This works for me. Others might want to customize the name of the synthesized object in serialization. Also the deserialization is not very robust or flexible.



来源:https://stackoverflow.com/questions/28516550/skip-level-when-parse-with-gson

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!