【问题标题】:How can I serialize a nested object using Gson @SerializedName in Java?如何在 Java 中使用 Gson @SerializedName 序列化嵌套对象?
【发布时间】:2019-06-15 21:13:30
【问题描述】:

我有twitter 数据。此数据中有一些nested 对象。我想将这些字段收集到Java 中的单个对象中。 我正在使用 @SerializedName 注释将一些嵌套字段导入到我的 java 对象中。

我的示例 json 如下所示:

{
  "created_at": "Sat Jun 15 19:21:29 +0000 2019",
  "text": "RT @BuzzTechy: [BEST] Udemy Course - Create a Python Powered Chatbot in Under 60 Minutes  \n\nhttps:\/\/t.co\/jMIW38FmmZ \n\n#AI #Python #Chatbot\u2026",
  "source": "\u003ca href=\"https:\/\/allentowngroup.com\" rel=\"nofollow\"\u003ebobbidigi\u003c\/a\u003e",
  "truncated": false,
  "in_reply_to_screen_name": "asdsf"
  "user": {
    "id": 1724601306,
    "name": "Rob's Coding News In The Hood"
  }
}

还有我的 java 对象:

public class TweetEntity implements Serializable {

private static long serialVersionUID = 1L;

@SerializedName("created_at")
private Date createdAt;

private String text;

private String source;

private Boolean truncated;

@SerializedName("in_reply_to_screen_name")
private String inReplyToScreenName;

@SerializedName("user.name")
private String userName;

}

但这不起作用。有没有人对此有任何想法或知识?

【问题讨论】:

    标签: java json serialization gson


    【解决方案1】:

    得到了上一个答案的更简单的版本

    
    public class TweetEntity {
    
      ...
    
      @SerializedName("user")
      @JsonAdapter(UsernameDeserializer.class)
      private String userName;
    }
    
    public static class UsernameDeserializer implements JsonDeserializer<String> {
        @Override
        public String deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) {
            return json.getAsJsonObject().get("name").getAsString();
        }
    }
    

    【讨论】:

      【解决方案2】:

      如果您不想拥有单独的用户对象,而是将 userName 作为 TweetEntity 中的属性,您可以执行以下操作:

      • 编写自定义 TweetEntity 反序列化器
      • 通过调用 getAsJsonObject 两次(在用户和名称上)提取用户名
      • 以正常方式反序列化 TweetEntity(使用正确的日期格式)
      • 在 TweetEntity 上设置用户名

      测试

      为了能够进行测试,我们需要访问 TweetEntity 中的一些属性:

      Date getCreatedAt() {
          return createdAt;
      }
      
      void setUserName(String userName) {
          this.userName = userName;
      }
      String getUserName() {
          return userName;
      }
      

      TweetEntity 反序列化器

      您的示例中使用的日期字符串如下所示:

      Sat Jun 15 19:21:29 +0000 2019
      

      对于这样的日期,您必须为反序列化指定自定义格式。

      对应的日期格式为:

      E MMM dd hh:mm:ss Z yyyy
      

      所以我们首先提取用户 JsonElement 并从那里提取名称 JsonElement。 在使用自定义日期格式(并且缺少 userName)反序列化 TweetEntity 实例后,我们可以设置 userName 属性。

      在代码中是这样的:

      import com.google.gson.*;
      import java.lang.reflect.Type;
      
      
      public class TweetEntityDeserializer implements JsonDeserializer<TweetEntity> {
      
          @Override
          public TweetEntity deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
              JsonElement user = json.getAsJsonObject().get("user");
              JsonElement userName = user.getAsJsonObject().get("name");
      
              Gson g = new GsonBuilder().setDateFormat("E MMM dd hh:mm:ss Z yyyy").create();
              TweetEntity entity = g.fromJson(json, TweetEntity.class);
              entity.setUserName(userName.getAsString());
              return entity;
          }
      
      }
      

      测试

      让我们用一个小的、独立的 Java 程序来试试吧。

      import com.google.gson.*;
      
      public class Main {
      
          public static void main(String[] args) {
              String json = "{\"created_at\":\"Sat Jun 15 19:21:29 +0000 2019\",\"text\":\"RT @BuzzTechy: [BEST] Udemy Course - Create a Python Powered Chatbot in Under 60 Minutes  \\n\\nsomeUrl \\n\\n#AI #Python #Chatbot?\",\"source\":\"<a href=\\\"https://allentowngroup.com\\\" rel=\\\"nofollow\\\">bobbidigi</a>\",\"truncated\":false,\"in_reply_to_screen_name\":\"asdsf\",\"user\":{\"id\":1724601306,\"name\":\"Rob's Coding News In The Hood\"}}";
              Gson g = new GsonBuilder()
                      .registerTypeAdapter(TweetEntity.class, new TweetEntityDeserializer())
                      .create();
              TweetEntity entity = g.fromJson(json, TweetEntity.class);
              System.out.println("created at: " + entity.getCreatedAt());
              System.out.println("userName: " + entity.getUserName());
          }
      
      }
      

      输出到控制台

      created at: Sat Jun 15 21:21:29 CEST 2019
      userName: Rob's Coding News In The Hood
      

      因此,userName 字段在没有嵌套到 TweetEntity 对象中的情况下被收集,并且观察到了自定义日期格式。所以它有效!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-09-05
        • 2023-04-10
        • 2022-01-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多