1

I have some Json (fragment displayed) that I'm finding awkward to parse using Gson. I can parse the rest of the json. The way I read the json fragment below, I have an array called arguments containing an object type, another array type, and a string type. I am unable to change the Json.

Has anybody got any ideas on how to parse this using Gson?

"arguments": [
    {
        "codes": [
            "memberRequest.email",
            "email"
        ],
        "arguments": null,
        "defaultMessage": "email",
        "code": "email"
    },
    [],
    ".*"
]
2
  • I'm not familiar with GSON, so there could certainly be something about this question that I don't understand, but valid JSON is valid JSON--any compliant parser should just parse it. (Also, FWIW, what you posted isn't JSON, rather it seems to be an excerpt from some JSON) Commented May 17, 2016 at 16:43
  • Yes, you're right. It is an excerpt. I'll update the question to reflect that. I'm trying to imagine a java object that might represent this json, as gson can use such an object to map json parameters to. However, java does not support multitype arrays, there is no common parent to these types other than Object, and there in lies the problem (I think) - but this must be so common, there must be a solution. Commented May 17, 2016 at 17:19

1 Answer 1

1

It depends on what data structure you would like to have in your java representation. There are 3 options you can choose from:

Option 1 List or List<Object> (Actualy Objects would be LinkedHashMap, String, ArrayList)

new Gson().fromJson(JSON, ParentPOJO.class);

private static class ParentPOJO{
   public List<Object> arguments;
}

Option 2 Custom MyListClass with custom deserializer for MyListClass where MyListClass extends ArrayList This way you can contol deserialization and choose appropriate data type for you objects. This will give you MyListClass extends ArrayList containing MyClass, ArrayList and String. Demo below.

public static void main(String[] args) {
    Gson gson = new GsonBuilder().registerTypeAdapter(MyListClass.class, new CustomDeserializer()).create();
    map = gson.fromJson(JSON, ParentPOJO.class);
}

private static class ParentPOJO{
    public MyListClass arguments;
}

private static class MyListClass extends ArrayList{}

private static class CustomDeserializer implements JsonDeserializer{

    @Override
    public Object deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        MyListClass list = null;
        if (json.isJsonArray()){
             list  = new MyListClass();
            JsonArray array = json.getAsJsonArray();

            for(int i = 0; i< array.size();i++){
                Object next = parseNext(array.get(i),context);
                list.add(next);
            }
        }

        return list;
    }
    private Object parseNext(JsonElement json, JsonDeserializationContext context){
        if (json.isJsonArray()){
            return context.deserialize(json, Object.class);//can change object type if you know it
        }else if(json.isJsonPrimitive()){
            return json.getAsJsonPrimitive().getAsString();
        }else if(json.isJsonObject()){
            return context.deserialize(json, MyClass.class);
        }
        return null;
    }
}

public class MyClass {
    @SerializedName("codes")
    private List<String> codes = new ArrayList<String>();
    @SerializedName("arguments")
    private Object arguments;
    @SerializedName("defaultMessage")
    private String defaultMessage;
    @SerializedName("code")
    private String code;
}

Option 3 is almost exactly the same, but MyPOJOClass instead of MyListClass just change deserializer, add fields to your MyPOJOClass and map json array to pojo fields in deserializer. Will also have to create custom serializer if you choose 3-d option of custom MyPOJOClass

If you have multiple objects of the same type in your json array you will have to come up with some sort of algorithm to resolve them in deserializer.

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

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.