Nesting multiple levels of Jackson WRAPPER_OBJECTs
jackson, java, json, wrapper
Solution
By default wrapping root node in Jackson is disabled. You can wrap inner objects but if you want to wrap root node you need to enable jackson feature for it (https://jira.codehaus.org/browse/JACKSON-747):
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationConfig.Feature.WRAP_ROOT_VALUE);
objectMapper.enable(DeserializationConfig.Feature.UNWRAP_ROOT_VALUE);
When you enabled these features you already said Jackson to wrap the root element and you don't need @JsonTypeInfo and @JsonTypeName anymore. You can simple delete them. But now you need to customize the root node name and you can use @JsonRootName for it. Your classes should look like this:
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonRootName("amountTransaction")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class AmountTransaction {
private String clientCorrelator;
private String endUserId;
...............
}
And
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonRootName("paymentTransactionNotification")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class PaymentTransactionNotification {
private AmountTransaction amountTransaction;
.............
}
I've tried and Jackson converted both JSON requests as expected.
Problem
By no means am I a Jackon/JSON wizard, which is probably evident from the following issue I'm running into: I have 2 possible data structures I'm receiving. The first one is called amountTransaction: ``` { "amountTransaction": { "clientCorrelator":"54321", "endUserId":"tel:+16309700001" } } ``` Which is represented by the following Java object: ``` @JsonIgnoreProperties(ignoreUnknown = true) @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT) @JsonTypeName(value = "amountTransaction") @JsonInclude(JsonInclude.Include.NON_NULL) public class AmountTransaction { private String clientCorrelator; private String endUserId; ... } ``` However the amountTransaction object also appears as child element of the paymentTransactionNotification object: ``` { "paymentTransactionNotification": { "amountTransaction": { "clientCorrelator": "54321", "endUserId": "tel:+16309700001" } } } ``` ..which I thought would be represented by: ``` @JsonIgnoreProperties(ignoreUnknown = true) @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT) @JsonTypeName(value = "paymentTransactionNotification") @JsonInclude(JsonInclude.Include.NON_NULL) public class PaymentTransactionNotification { private AmountTransaction amountTransaction; ... } ``` Parsing the JSON with the amountTransaction object alone works fine. It's a pretty straightforward example of a WRAPPER_OBJECT. However when trying to parse the JSON for the paymentTransactionNotification, I'm getting an exception indicating that it can't properly deal with the amountTransaction as element of the paymentTransactionNotification: ``` com.fasterxml.jackson.databind.JsonMappingException: Could not resolve type id 'clientCorrelator' into a subtype of [simple type, class com.sf.oneapi.pojos.AmountTransaction] ``` Any thoughts on how I can properly annotate this so my code can properly deal with both stand alone, as well as encapsulated amountTransaction objects?