Peter Kronenberg
Peter Kronenberg

Reputation: 1296

Can Jackson accept both wrapped and unwrapped Json when using JsonUnwrapped

I have a class like this:

...
@JsonUnwrapped
private DataObject dataObject;
...

Data object is

@Getter
public class DataObject {
    private String nested1;
    private String nested2;
}

Obviously, this will work if my Json input is

{
   "nested1" : "nestedValue1", 
   "nested2" : "nestedValue2"
}

Is there a way to make it flexible so that it can accept both versions? But what if I want it to also be able to accept

{
   "dataObject: {
      "nested1" : "nestedValue1", 
      "nested2" : "nestedValue2"
   }
}

Upvotes: 0

Views: 771

Answers (1)

dariosicily
dariosicily

Reputation: 4527

Taking the code of your TestContract class from your previous question below :

public class TestContract {
    private String field1;

    @JsonUnwrapped
    private DataObject dataObject;
}

One way to solve the problem is to write a custom deserializer for your TestContract class that will use the following lombok annotations and the @JsonDeserialize annotation :

@Getter
@Setter
@ToString
@NoArgsConstructor
@JsonDeserialize(using = TestContractDeserializer.class)
public class TestContract {
    private String field1;

    @JsonUnwrapped
    private DataObject dataObject;
}

The custom deserializer will check the field1 property and after will check if the two nested1 and nested2 properties are nested or not inside the dataObject property covering both cases you presented :

public class TestContractDeserializer extends JsonDeserializer<TestContract> {

    @Override
    public TestContract deserialize(JsonParser jp, DeserializationContext dc) throws IOException, JsonProcessingException {
        JsonNode node = jp.getCodec().readTree(jp);
        //read the field1 property
        String field1 = node.get("field1").asText();
        JsonNode dataObjectNode = node.get("dataObject");
        //check if properties are nested or not
        if (dataObjectNode != null) {
            node = dataObjectNode;
        }
        String nested1 = node.get("nested1").asText();
        String nested2 = node.get("nested2").asText();
        DataObject dataObject = new DataObject();
        dataObject.setNested1(nested1);
        dataObject.setNested2(nested2);
        TestContract testContract = new TestContract();
        testContract.setDataObject(dataObject);
        testContract.setField1(field1);
        return testContract;
    }
}

Upvotes: 1

Related Questions