如何在Java中使用Gson @SerializedName序列化嵌套对象?

时间:2019-06-15 21:13:30

标签: java json serialization gson

我有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;

}

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

2 个答案:

答案 0 :(得分:1)

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

  • 编写自定义的TweetEntity Deserializer
  • 通过两次调用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。 使用自定义日期格式(缺少用户名)反序列化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对象中,并且会观察到自定义日期格式。这样就行了!

答案 1 :(得分: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();
    }
}