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?
A JsonNode is Jackson's tree model for JSON and it can read JSON into a JsonNode instance and write a JsonNode out to JSON. To read JSON into a JsonNode with Jackson by creating ObjectMapper instance and call the readValue() method. We can access a field, array or nested object using the get() method of JsonNode class.
@JsonRootName allows to have a root node specified over the JSON. We need to enable wrap root value as well.
@JsonUnwrapped is used to unwrap values of objects during serialization or de-serialization.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With