Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jackson JSON to Java mapping for same attrubute with different data type

I have a JSON object which I don't have control of and want to map it to a Java object which is pre-created. There is one attribute in the JSON object which can be a URL or it could be a JSONArray.

Class SomeClass {

    private URL items;

    public URL getURL() {
        return items;
    }

    public void setURL(URL url) {
        this.items = url;
    }
}

Below is the JSON:

Case A:

{
...
    items: http://someurl.abc.com/linktoitems,
...
}

OR

Case B

{
...
    items: [
            { "id": id1, "name": name1 },
            { "id": id2, "name": name2 }
           ]
...
}

If i create the POJO to map for Case A, Case B fails and vice versa. In short, is there a way to map the JSON attribute to the POJO field with different data types? In that case I will create two separate fields in the POJO named,

private URL itemLink;
private Item[] itemList;
like image 669
user788052 Avatar asked Nov 05 '22 19:11

user788052


1 Answers

It depends on exact details, but if what you are asking is if it is possible to map either JSON String or JSON array into a Java property, yes this can be done.

Obvious way would be to define a custom deserializer which handles both kinds of JSON input. But it is also possible to define Java type in such a way that it can be constructed both by setting properties (which works from JSON Object) and have a single-String-arg constructor or static single-String-arg factory method marked with @JsonCreator.

Yet another possibility is to use an intermediate type that can deserialized from any JSON: both java.lang.Object and JsonNode ("JSON tree") instances can be created from any JSON. From this value you would need to do manual conversion; most likely in setter, like so:

public void setItems(JsonNode treeRoot) { .... }

What will not work, however, is defining two properties with the same name.

One thing I don't quite follow is how you would convert from List to URL though. So maybe you actually do need two separate internal fields; and setter would just assign to one of those (and getter would return value of just one).

like image 84
StaxMan Avatar answered Nov 09 '22 11:11

StaxMan