【问题标题】:Can I access inner layer of JSON using GSON with SerializedName我可以使用带有 SerializedName 的 GSON 访问 JSON 的内层吗
【发布时间】:2015-04-24 04:33:03
【问题描述】:

假设有这样的 JSON

{
  "data" : {
    "messages" : {
      "count" : 2,
      "data" : [
        "message 1",
        "message 2"
      ]
    },
    "user" : {
      "f_name" : "Mark",
      "l_name" : "lewis"
    },
    "city" : "London",
    "address" : "221b Baker Street, London"
  }
}

我可以使用 GSON 实现这样的目标吗?

public class JSData {
    public String city;
    public String address;
    public Array messages;
    @SerializedName("user.f_name")
    public String firstName;
    @SerializedName("user.l_name")
    public String lastName;
}

我想直接访问user.f_name,所以我不必为user创建包装器,可以直接使用转换它

 JSData topic = gson.fromJson(jsonObj, JSData.class);

【问题讨论】:

标签: android gson


【解决方案1】:

我认为你应该像这样创建一个类用户

    public class User {
        @SerializedName("f_name")
        public String firstName;

        @SerializedName("l_name")
        public String lastName;
    }

    public class JSData {
        public String city;
        public String address;
        public Array messages;

        @SerializedName("user")
        public User user;
    }

【讨论】:

  • 我知道如何使用它,但我想知道我是否可以在不创建 User 包装器的情况下将 f_name 和 l_name 放入 JSData。
  • 我认为我们使用 JsonDeserializer 有一个复杂的解决方案。
【解决方案2】:

我不知道如何归档 @SerializedName("user.f_name") 这样的方式,
但是由于JsonDeserializer,扁平化的内部字段是可以归档的。

假设我们有

 {   
   "publishDate": {
     __type: "Date",
     iso: "2014-11-05T02:27:00.000Z"
    },
 ...
 }

我们想将内部“iso”字段转换为上层“publishDate”为Date

所以,JsData 类看起来像这样。

public class JsData {
  // publishDate is JSONObject. but get it as Date!
  public Date publishDate;
  ...
}

实现JsonDeserializer<Date> 并注册到 gson 以存档自定义反序列化。当 gson 检测到Date 字段时,将调用此实现。

public static class PublishDateDeserializer implements JsonDeserializer<Date> {
    @Override
    public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
        throws JsonParseException {
      // this deserializer is only for "publishDate"
      // real json is jsonobject. get inner "iso"
      String iso = json.getAsJsonObject().get("iso").getAsString();
      DateFormat parser = new SimpleDateFormat(DATE_JSON_PATTERN);
      try {
        return parser.parse(iso);
      } catch (ParseException e) {
        throw new JsonParseException(e);
      }
    }
  }

然后通过builder注册

Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new PublishDateDeserializer()).create();
gson.fromJson(json, JsData.class);

我希望它会有所帮助。

【讨论】:

  • 我认为这个答案似乎离题了。他想在没有任何其他包装类的情况下将内部数组放入 JSData。
  • 是的,我知道这不是完美的解决方案。但是内部字段(f_name 为他,iso 为我)转换为上层。 “包装类”是什么意思?
猜你喜欢
  • 2021-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-09
  • 2016-04-17
  • 2018-02-25
  • 1970-01-01
相关资源
最近更新 更多