【问题标题】:Skip level when parse with Gson使用 Gson 解析时跳过级别
【发布时间】:2015-04-15 11:53:33
【问题描述】:

我有一些 json 格式看起来像:

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

我创建了一些模型,如下所示:

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

class Detail{
   // Define something.
}

最后我创建了类名 UserWapper。

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

解析json:

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

但目前我不想创建类 Wrapper。因为我有很多很多的课。如果创建 WrapperClass -> :|

我想做这样的事情:

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

(注意:我无法从服务器更改格式数据 json。我还 gg 搜索了一些自定义 gson 适配器,但我找不到跳过“级别”另一个字段的方法)。

【问题讨论】:

    标签: json gson


    【解决方案1】:

    如果您不想要包装类,可以将 json 字符串解析为 JsonObject,然后获取其 user 对象,并将用户对象反序列化为您的 User 类的实例。

    试试下面的代码:

    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);
    

    输出:

    user.name:名称
    用户年龄:99

    【讨论】:

    • 嗨,如你所见。我们仍然需要添加一个步骤来获取字符串内部“根”obj。我们能不能把它简化为:User u = gson.fromJson(json, User.class).
    • @quangson91 不,除非您想编写自定义的 TypeAdapter 或 JsonSerialzer,否则无法完成,这会使其变得更加困难。简单的解决方案是编写一个包装器或获取内部 json 元素并按照我在回答中的描述对其进行解析。这是最简单的方法。
    • 您使用 Google Map Api 吗?我经常看到数据响应将包装“根”对象:| (我认为如果我们创建太多 Wrapper 类,会非常卡)。
    【解决方案2】:

    我刚刚实现了另一种方法:在仅包含包装器对象的字段上注释 JsonAdapter。 JsonAdapter 实际上是一个 TypeAdapterFactory,像这样:

    /**
     * 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;
                }
            };
        }
    }
    

    这对我有用。其他人可能希望在序列化中自定义合成对象的名称。此外,反序列化也不是很健壮或灵活。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-23
      • 1970-01-01
      • 2018-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-03
      相关资源
      最近更新 更多