3

I have twitter data. There are some nested objects in this data. I want to gather these fields into a single object in Java. I'm using @SerializedName anotation to import some of the nested fields into my java object.

My sample json looks like this:

{
  "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"
  }
}

And my java object:

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;

}

But this does not work. Does anyone have any idea or knowledge about it?

0

2 Answers 2

7

Got a little simpler version of the previous answer working


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();
    }
}
Sign up to request clarification or add additional context in comments.

Comments

3

If you don't want to have a separate user object but instead having userName as a property in TweetEntity you can do the following:

  • write a custom TweetEntity Deserializer
  • extract the user name via calling getAsJsonObject twice (on user and on name)
  • deserialize a TweetEntity the normal way (using correct date format)
  • set user name on TweetEntity

Test

To be able to test we need to access some properties in TweetEntity:

Date getCreatedAt() {
    return createdAt;
}

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

TweetEntity Deserializer

The date string used in your example looks like this:

Sat Jun 15 19:21:29 +0000 2019

For such a date, you must specify a custom format for deserialization.

The corresponding date format is:

E MMM dd hh:mm:ss Z yyyy

So we a first extracting the user JsonElement and from there the name JsonElement. After deserializing a TweetEntity instance with the custom date format (and missing userName), we can then set the userName property.

In code it looks like this:

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

Let's try it with a small, self-contained Java program.

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

}

Output to Console

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

So the userName field is gathered without nesting into the TweetEntity object as well as the custom date format is observed. So it works!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.