Search code examples
javajsonspringjacksonobjectmapper

Jackson ObjectMapper set JsonFormat.Shape.ARRAY without annotation


I need to use two jackson 2 object mappers. Both mappers work with the same set of classes. In the first I need to use standard serialization. In the second i want to use ARRAY shape type for all classes (see https://fasterxml.github.io/jackson-annotations/javadoc/2.2.0/com/fasterxml/jackson/annotation/JsonFormat.Shape.html#ARRAY).

But i want to global set this feature for my second ObjectMapper. Something like mapper.setShape(...)

How to do it?

UPD:

I found a way to override the config for the class:

mapper.configOverride(MyClass.class)
   .setFormat(JsonFormat.Value.forShape(JsonFormat.Shape.ARRAY));

So I can change for all my classes using Reflection API.

It is embarrassing that I override the global setting, but I can not directly set it.


Solution

  • As @JsonFormat annotation works on field, you can't set it to Shape.Array at global level. This would mean all the fields would be serialized and deserialised into array values (imagine if a field is already a list, in this case, it will be wrapped into another list which is something we might not want).

    You can however, write your own serializer for a type (that converts a value into an array) and configure it in ObjectMapper, e.g.:

    class CustomDeserializer extends JsonSerializer<String>{
    
        @Override
        public void serialize(String value, JsonGenerator gen, SerializerProvider serializers)
                throws IOException, JsonProcessingException {
            gen.writeStartArray();
            gen.writeString(value);
            gen.writeEndArray();
        }
    }
    

    And configure it to ObjectMaper instance, e.g.:

    ObjectMapper mapper = new ObjectMapper();
    SimpleModule module = new SimpleModule();
    module.addSerializer(String.class, new CustomDeserializer());
    mapper.registerModule(module);