1

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.

14
  • What do you want to with this "hi" value? Store it in the list? Discard it? Commented Apr 4, 2015 at 22:26
  • Oh yeah - I'm trying to put it in a variable, in this case the "text" variable (its the actual text whereas the rest here is the formatting) if it helps any, here is the documentation on the actual json string used here: wiki.vg/Chat Commented Apr 4, 2015 at 22:28
  • The documentation you linked does not show this particular structure (speaking about the with array). Anyway you could write a custom deserializer to parse this JSON as you want. Commented Apr 4, 2015 at 22:35
  • Is there any chance you could put me on the right track for doing that? I'm rather new to Gson. Commented Apr 4, 2015 at 22:37
  • Sure but I'm not very sure about which final structure you need, so if you could clarify things that would help. Commented Apr 4, 2015 at 22:38

1 Answer 1

5

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.

Sign up to request clarification or add additional context in comments.

1 Comment

@Alexis, can you tell me something about Generic type the way you have implemented in code, I have little knowledge( like how to use in ArrayList<String>) about them and want to learn how to work with generics

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.