简体   繁体   中英

How to deserialize a subclass with Gson?

I have a Message class and a HistoryMessage class which extends Message . How I can deserialize HistoryMessage using Gson?

public class Message
{
    @SerializedName("id")
    private int id;

        @SerializedName("date")
        private long date;

        @SerializedName("out")
        private int out;

        @SerializedName("user_id")
        private int userId;
        public Message(int id, long date, int userId, int out)
        {
            this.id = id;
            this.date = date;
            this.userId = userId;
            this.out = out;
        }
    }
        public class MessageHistory extends Message
        {          
            @SerializedName("from_id")
            private int fromId;
            public MessageHistory(int id, long date, int userId, int out, int fromId)
            {
                super(id, date, userId, out);
                this.fromId = fromId;
            } 
       }

And I have class - Dialog, that is container for all messages

public class Dialog  {
    private int count;
    private ArrayList<Message> dialogs = new ArrayList<Message>();

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public ArrayList<Message> getDialogs() {
        return dialogs;
    }

    public void setDialogs(Message dialogs) {
       this.dialogs.add(dialogs);
    }
}

and deserializer for Message , but I don't know how I can deserialize a HistoryMessage .

public Dialog deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
    Dialog dialog = new Dialog();
    JsonArray jsonArray = (JsonArray)json.getAsJsonObject().get("response").getAsJsonObject().get("items");
    int count = (Integer)json.getAsJsonObject().get("response").getAsJsonObject().get("count").getAsInt();

    for ( int i = 0; i < jsonArray.size(); i++ ) {
        JsonElement jsonElement = jsonArray.get(i);
        Message message = new Message();
        boolean unread = false;

        if ( jsonElement.getAsJsonObject().has("unread")){
            unread = true;
        }
        JsonObject object = (JsonObject)jsonElement.getAsJsonObject().get("message");
        message = context.deserialize(object, Message.class);
        message.setUnread(unread);
        dialog.setDialogs(message);
    }

    dialog.setCount(count);
    return  dialog;
}

To use Gson you need to specify which type you want to deserialize into. If you want to construct a HistoryMessage instance, you need to pass HistoryMessage.class to your fromJson() call. If you don't know what type you'll be trying to construct at compile time, you can hack around it by storing the type in the JSON like this answer describes: How to serialize a class with an interface?

That's definitely not a best practice though. Needing to do this suggests you may be trying to deserialize into types that are too complex. Consider splitting your deserializing code from your business logic, eg deserialize your JSON into an intermediary class, then construct your HistoryMessage from that class, rather than directly from the JSON.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM