Search code examples
javajacksonjson-deserialization

Using jackson deserialising a property which can be List of object or the object


My lib is calling an API which can return either of the following JSON structure -

{
  "key_is_same" : {
     "inner" : "val"
  } 
}

-or-

 {
  "key_is_same" : [{
     "inner" : "val1"
    },
    {
     "inner" : "val2"
    }
  ]
}

Is there any annotation in jakson which can handle this and deserializ it into respective type


Solution

  • Looks like you are looking for the ACCEPT_SINGLE_VALUE_AS_ARRAY deserialization feature.

    Feature that determines whether it is acceptable to coerce non-array (in JSON) values to work with Java collection (arrays, java.util.Collection) types. If enabled, collection deserializers will try to handle non-array values as if they had "implicit" surrounding JSON array. This feature is meant to be used for compatibility/interoperability reasons, to work with packages (such as XML-to-JSON converters) that leave out JSON array in cases where there is just a single element in array.

    Feature is disabled by default.

    It could be enabled either in ObjectMapper:

    ObjectMapper mapper = new ObjectMapper();
    mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
    

    Or via the @JsonFormat annotation:

    @JsonFormat(with = Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
    private List<Foo> oneOrMany;
    

    For illustration purposes, consider the following JSON documents:

    {
      "oneOrMany": [
        {
          "value": "one"
        },
        {
          "value": "two"
        }
      ]
    }
    
    {
      "oneOrMany": {
        "value": "one"
      }
    }
    

    It could be the deserialized to the following classes:

    @Data
    public class Foo {
        private List<Bar> oneOrMany;
    }
    
    @Data
    public class Bar {
        private String value;
    }
    

    Just ensure the feature is enabled in your ObjectMapper or your field is annotated with @JsonFormat(with = Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY).


    And in case you are looking for the equivalent feature for serialization, refer to WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED.