2

I am using Gson to convert JSON into a Java object. I have a field in the json that our wise services people coded as either an array or object depending on how many items come back in database. Question is how do model the Java object to pass into Gson converter so that I can handle both types?

json = new Gson().fromJson(reader, Order.class);

Java Classes only parses the JSON array properly

public class Order {
    private Detail detail
}

public class Detail {
    public String id;
    public List<Type> types;
    //// getters and setters
}

public class Type {
    public String typeId;
    public String typeName
    //// getters and setters
}

JSON data array

{
    "detail":{
        "id":"1234565",
        "types":{
            "type":[
                {"typeId":"1246565","typeName":"MyName1"},
                {"typeId":"1444445","typeName":"MyName2"}
            ]
        }
    }
}

JSON data object

{
    "detail":{
        "id":"1234565",
        "types":{
            "type":{"typeId":"1246565","typeName":"MyName1"}
        }
    }
}
8
  • Isn't there a way, in GSON, to ask what the type of an element is? Commented Jul 18, 2014 at 17:32
  • 2
    As you allude, you're working with poor service design. Can you talk with the data services people to use only the first type (the JSON data array) even if there is only one item from the database? That would make it easier for not just you, but other developers/teams that are working with the service in the future. Commented Jul 18, 2014 at 17:34
  • Eg, isJsonArray and isJsonObject. (I found these in 30 seconds, and I don't even use GSON.) Commented Jul 18, 2014 at 17:34
  • I have no choice the services are set and have to stay that way due to legacy...I am just trying to no longer hand parse the objects and use Gson to auto parse. Commented Jul 18, 2014 at 17:46
  • what is you exact question? Do you want to convert both the JSON string into java object and it's not known in advance. Commented Jul 18, 2014 at 20:20

2 Answers 2

1

I figured out how to do this by using a generic object. So now I can still call using GSON and not have to do that much manual parsing only when I need when I reconstitute the Objects, and only that particular object.

json = new Gson().fromJson(reader, Order.class);

Main Object

public class Order {
    private Detail detail
}

Detail Class

public class Detail {
    public String id;
    public Types types;

    //// getters and setters
    public Types getTypes() {
        return types;
    }

    public void setTypes(Types types) {
        this.types = types;
    }
}

Types class that contains a generic Object called type so it can store either a List or a LinkedTreeMap which is how JSONObject gets parsed. You have to then manually insert it into a new Type object .

public class Types {
    private Object type;

    //// getters and setters

    public Object getType() {
        return type;
    }

    public void setType(Object type) {
        this.type = type;
    }

    public List<Type> getListType() {
        if (type instanceof List) {
            return (List<Type>) type;
        } else
            return null;
    }

    public Type getObjectType() {
        if (type instanceof Type) {
            return (Type) type;
        } else if (type instanceof Map) {
            Map<String, String> map = (Map<String, String>)type;
            Type newType = new Type((String)map.get("typeId"), (String)map.get("typeName"));
            return newType;
        }
        return null;
    }

public class Type {
    private String typeId;
    private String typeName;

    public Type() {}

    public Type(String id, String name) {
        this.typeId = id;
        this.typeName = name;
    }

    //// getters and setters
    public String getTypeId() {
        return typeId;
    }

    public void setTypeId(String typeId) {
        this.typeId = typeId;
    }

    public String getTypeName() {
        return typeName;
    }

    public void setTypeName(String typeName) {
        this.typeName = typeName;
    }
}
Sign up to request clarification or add additional context in comments.

Comments

-1

Sigh!!

JsonArray typeArray; 
JsonElement typeElement = types.get("type"); 
if (typeElement.isJsonObject()) { 
    typeArray = new JsonArray();
    typeArray.add(typeElement); 
}
else {
    typeArray = (JsonArray)typeElement;
}
for (int i = 0; i < typeArray.size(); i++) {
    JsonObject typeObject = (JsonObject)(typeArray.get(i));
    typeObject.doSomethingWithThis();
}

2 Comments

I don't want to pull apart the JSON because I need to pile this into Java objects. The Java class I have is way more complex than I am showing, with multiple levels of Java Objects. Hence why I want to do it via Gson().fromJson(). I wanted find out if there was some way through annotations or some other method to do it in the Java Object class
@JPM - Well, put it back together and process it however you want.

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.