Nesting multiple levels of Jackson WRAPPER_OBJECTs
Asked Answered
N

1

10

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?

Niobe answered 20/11, 2014 at 10:58 Comment(1)
I think you should show how you think this should map to a POJO -- I am not quite clear on how it would work, because properties of a POJO have names, and your JSON seems to be missing that part of information.Tamanaha
P
7

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.

Protuberancy answered 27/11, 2014 at 7:14 Comment(2)
I was going to speak to soon and say it wasn't working yet but then I realized I forgot to set the Features on my Unit test objectMapper. So yeah, this works perfect. Only note is that in Jackson 2.4.0 the Feature constants have changed a bit: objectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE); objectMapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);Niobe
I also have similar question related to nested fields and I am confuse on how can I make nested level POJO and extract id from the last level of parentCategory? Wanted to see if you can help me out.Stanhope

© 2022 - 2024 — McMap. All rights reserved.