Reputation: 18549
basically, my problem is that i have a list of wrapper objects
{"stuff": [
{"foobar" : {someObjectOfTypeA}},
{"barfoo" : {someObjectOfTypeB}},
{"foobar" : {someObjectOfTypeA}}
]}
and the type of someObjectOfTypeX depends on the value of the key "foobar" or "barfoo". how can i deserialize this? (for now) serializing is not a problem.
i don't know enough jackson to solve the following problem. i've tried, but i'm stuck.
the json structure i want to parse looks like this:
{
"id": "foobar",
"responses": [
{
"responseType1": {
"code": 0,
"foo": "bar"
}
},
{
"responseType2": {
"code": 1,
"bar": {"foo": ...}
}
},
{
"responseType1": {
"code": 1,
"foo": "foobar"
}
}
]
}
i tried to deserialize it using jacksons full data binding. my pojos are:
// pseudocode
// the outermost object
@JsonCreator
ServiceResponse(
@JsonProperty("id") String id,
@JsonProperty("responses") ArrayList<ResponseWrapper> responses)
// every response has a wrapper. the wrapper is an object with just one key and one value. the value is an object of a certain class (ResponseTypeX extends AResponse), and the exact ResponseType is identified by the key (the key isn't the class name though).
@JsonCreator
ResponseWrapper(AResponse keyDependsOnTypeOfAResponse ???)
// base class for all responseTypeX classes
// all subclasses of AResponse have a code and a complex payload object
@JsonCreator
AResponse (
@JsonProperty("code") int code)
// one response type
// here, the payload is just a string, in reality it's a deep structure, so i dont want to parse this manually
@JsonCreator
ResponseType1 extends AResponse (
@JsonProperty("code") int code,
@JsonProperty("foo") String foo)
// one response type
@JsonCreator
ResponseType2 extends AResponse (
@JsonProperty("code") int code,
@JsonProperty("bar") SomeOtherObject foo)
as you can see, responses
is an array of wrapper objects; the "payload" class of the wrapper object is identified by the key (but the keys aren't a 1:1 match to class names). my ResponseTypeX's are limited, there are about 20 of them, so if i have to do a manual key:value type identification, i'm happy.
but is it possible to write a manual deserializer for the WrapperResponse object and continue deserializing its children with full data binding? if so, how?
i tried to just make the Wrapper accept all possible ResponseTypes as properties, hoping it would just nullify the "unset" ones, e.g.
@JsonCreator
ResponseWrapper(
@JsonProperty("responseKey1") ResponseType1 response1,
@JsonProperty("responseKey2") ResponseType2 response2,
@JsonProperty("responseKey3") ResponseType3 response3,
...)
but this failed, probably because all ResponseTypes are subclasses of AResponse and thus jackson gets confused.
Upvotes: 3
Views: 2033
Reputation: 66935
Some custom deserialization processing is necessary. I'd recommend including a simple registry (map) of foobar/barfoo-to-type entries in the solution, much like the sixth example in my old blog post from May 25, 2011, "Deserialize JSON with Jackson into Polymorphic Types - A Complete Example".
Upvotes: 3