Как я могу сериализовать вложенный объект, используя Gson @SerializedName в Java? - PullRequest
0 голосов
/ 16 июня 2019

У меня есть 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;

}

Но это не работает. У кого-нибудь есть идеи или знания об этом?

1 Ответ

1 голос
/ 16 июня 2019

Если вы не хотите иметь отдельный объект пользователя, но вместо этого имеете имя пользователя в качестве свойства в 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. После десериализации экземпляра 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;
    }

}

Test

Давайте попробуем это с небольшой автономной программой на 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, так как соблюдается пользовательский формат даты. Так работает!

...