Reputation: 1420
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?
Upvotes: 3
Views: 6481
Reputation: 2039
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();
}
}
Upvotes: 7
Reputation: 27106
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:
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!
Upvotes: 3