简体   繁体   中英

Parsing multiple types in a JSON array with gson

I am attempting to parse a JSON string using a POJO with gson, I have run into a snag however when attempting to read the following JSON array:

{"translate":"chat.type.text","with":[{"insertion":"woder22","clickEvent":{"action":"suggest_command","value":"/msg woder22 "},"hoverEvent":{"action":"show_entity","value":"{name:\"woder22\",id:\"bbd02ce0-24de-4683-8c8f-5d7e6b7dffa6\",}"},"text":"woder22"},"hi"]}

Everything works just fine until I get to the "with" part, I am trying to parse it by using the following POJOs

public class ChatMessage {
    private String text = "";
    private String translate;
    private List<With> with = new ArrayList<With>();
    private String score;
    private String selector;
    private List<Node> extra;
    private String bold = "false";
    private String italic = "false";
    private String underlined = "false";
    private String strikethrough = "false";
    private String obfuscated = "false";
    private String color;
    private Clicked clickEvent;
    private Hover hoverEvent;
    private String insertion;

    //getter and setter method here

}

class Node {
    private String color;
    private String text;

    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
    public String getText() {
        return text;
    }
    public void setText(String text) {
        this.text = text;
    }
}

class Clicked {
    private String action;
    private String value;

    public String getAction() {
        return action;
    }
    public void setAction(String action) {
        this.action = action;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
}

class Hover {
    private String action;
    private String value;

    public String getAction() {
        return action;
    }
    public void setAction(String action) {
        this.action = action;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
}

I have changed this to show all of the code

public class With {
    private String translate;
    private Clicked clickEvent;
    private Hover hoverEvent;
    private String insertion;
    private String text = "";

    //setter and getters

    public ChatMessage getNonNull(ChatMessage mes){
        if(this.text != null)mes.setText(this.text);
        if(this.translate != null)mes.setTranslate(this.translate);
        if(this.score != null)mes.setScore(this.score);
        if(this.selector != null)mes.setSelector(this.selector);
        if(this.extra != null)mes.setExtra(this.extra);
        if(this.bold != null)mes.setBold(this.bold);
        if(this.italic != null)mes.setItalic(this.italic);
        if(this.underlined != null)mes.setUnderlined(this.underlined);
        if(this.strikethrough != null)mes.setStrikethrough(this.strikethrough);
        if(this.obfuscated != null)mes.setObfuscated(this.obfuscated);
        if(this.color != null)mes.setColor(this.color);
        if(this.clickEvent != null)mes.setClickEvent(this.clickEvent);
        if(this.hoverEvent != null)mes.setHoverEvent(this.hoverEvent);
        if(this.insertion != null)mes.setInsertion(this.insertion);
        return mes;
    }
}

Now the problem is when Gson tries to parse this it of course runs into the problem that the second part of the "with" array is NOT a With object. My problem is that I have no idea how to deal with this. Any help would be greatly appreciated.

Edit1 What it is suppose to do: The with array is simply suppose to be a sort of "overwrite" as in any field from the main string can be overwritten and individually formatted inside. Thats what the null thing at the bottom of the With class is suppose to do, it is suppose to edit the main variables with their overwritten contents. The unnamed field is suppose to be the text variable here.

Here's how you could write a custom deserializer for this:

class ChatMessageDezerializer implements JsonDeserializer<ChatMessage> {
    @Override
    public ChatMessage deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        ChatMessage message = new ChatMessage();
        JsonObject obj = json.getAsJsonObject();
        message.translate = obj.get("translate").getAsString();
        JsonArray array = obj.getAsJsonArray("with");
        message.with.add(context.deserialize(array.get(0), With.class));
        message.with.add(array.get(1).getAsString());
        return message;
    }
}

and register it in your Gson parser:

Gson gson = new GsonBuilder().registerTypeAdapter(ChatMessage.class, new ChatMessageDezerializer()).create();

Note that with is now a List<Object> since the most specific common type to the elements in the array are Object. Also I just done the problematic part, the rest can be handled easily. Running this you end up with

[With@b1a58a3, hi]

as the resulting list. This assume you have a minimum control over the structure you get back (or at least you know in which format it would be). It should give you a good starting point from there.

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