Search code examples
javajsonjacksonannotationsjackson-databind

Is it possible to specify the order of ObjectNode properties without using annotations?


Jackson allows users to specify an explicit serialization order for ObjectNode properties using the @JsonProperty(index = ?) annotation. Meaning, given properties a, b, c I can instruct Jackson to serialize them in the following order: b, a, c. I control the exact serialization order.

Is it possible to achieve the same without the use of annotations?

I do not want alphabetic sorting. I want to specify an explicit sorting order.


Solution

  • You can extend com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector class and provide your order for any class you want by overriding findSerializationPropertyOrder method.

    import com.fasterxml.jackson.databind.SerializationFeature;
    import com.fasterxml.jackson.databind.introspect.AnnotatedClass;
    import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
    import com.fasterxml.jackson.databind.json.JsonMapper;
    import lombok.Data;
    
    public class JacksonAnnotationIntrospectorApp {
        private final static JsonMapper JSON_MAPPER = JsonMapper.builder()
                .enable(SerializationFeature.INDENT_OUTPUT)
                .annotationIntrospector(new DynamicOrderJacksonAnnotationIntrospector())
                .build();
    
        public static void main(String[] args) throws Exception {
            var pojo = new DynamicOrderPojo();
            pojo.setA("A");
            pojo.setB(1);
            pojo.setC(3.33);
    
            JSON_MAPPER.writeValue(System.out, pojo);
        }
    }
    
    class DynamicOrderJacksonAnnotationIntrospector extends JacksonAnnotationIntrospector {
    
        @Override
        public String[] findSerializationPropertyOrder(AnnotatedClass ac) {
            if (ac.getRawType() == DynamicOrderPojo.class) {
                return new String[]{"b", "a", "c"};
            }
            return super.findSerializationPropertyOrder(ac);
        }
    }
    
    @Data
    class DynamicOrderPojo {
    
        private String a;
        private Integer b;
        private Double c;
    }
    

    Above code prints:

    {
      "b" : 1,
      "a" : "A",
      "c" : 3.33
    }
    

    See also: