How to specify jackson to only use fields - preferably globally

前端 未结 8 525
旧巷少年郎
旧巷少年郎 2020-11-22 17:03

Default jackon behaviour seems to use both properties (getters and setters) and fields to serialize and deserialize to json.

I would like to use the fields as the ca

相关标签:
8条回答
  • 2020-11-22 17:35

    If you want a way to do this globally without worrying about the configuration of your ObjectMapper, you can create your own annotation:

    @Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @JacksonAnnotationsInside
    @JsonAutoDetect(
            getterVisibility = JsonAutoDetect.Visibility.NONE, isGetterVisibility = JsonAutoDetect.Visibility.NONE,
            setterVisibility = JsonAutoDetect.Visibility.NONE, fieldVisibility = JsonAutoDetect.Visibility.NONE,
            creatorVisibility = JsonAutoDetect.Visibility.NONE
    )
    public @interface JsonExplicit {
    }
    

    Now you just have to annotate your classes with @JsonExplicit and you're good to go!

    Also make sure to edit the above call to @JsonAutoDetect to make sure you have the values set to what works with your program.

    Credit to https://stackoverflow.com/a/13408807 for helping me find out about @JacksonAnnotationsInside

    0 讨论(0)
  • 2020-11-22 17:36

    for jackson 1.9.10 I use

    ObjectMapper mapper = new ObjectMapper();
    
    mapper.setVisibility(JsonMethod.ALL, Visibility.NONE);
    mapper.setVisibility(JsonMethod.FIELD, Visibility.ANY);
    

    to turn of auto dedection.

    0 讨论(0)
  • 2020-11-22 17:36

    @since 2.10 version we can use JsonMapper.Builder and accepted answer could look like:

    JsonMapper mapper = JsonMapper.builder()
        .visibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY)
        .visibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE)
        .visibility(PropertyAccessor.SETTER, JsonAutoDetect.Visibility.NONE)
        .visibility(PropertyAccessor.CREATOR, JsonAutoDetect.Visibility.NONE)
        .build();
    
    0 讨论(0)
  • 2020-11-22 17:44

    You can configure individual ObjectMappers like this:

    ObjectMapper mapper  = new ObjectMapper();
    mapper.setVisibility(mapper.getSerializationConfig().getDefaultVisibilityChecker()
                    .withFieldVisibility(JsonAutoDetect.Visibility.ANY)
                    .withGetterVisibility(JsonAutoDetect.Visibility.NONE)
                    .withSetterVisibility(JsonAutoDetect.Visibility.NONE)
                    .withCreatorVisibility(JsonAutoDetect.Visibility.NONE));
    

    If you want it set globally, I usually access a configured mapper through a wrapper class.

    0 讨论(0)
  • 2020-11-22 17:48

    How about this: I used it with a mixin

    non-compliant object

    @Entity
    @Getter
    @NoArgsConstructor
    public class Telemetry {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long pk;
        private String id;
        private String organizationId;
        private String baseType;
        private String name;
        private Double lat;
        private Double lon;
        private Instant updateTimestamp;
    }
    

    Mixin:

    @JsonAutoDetect(fieldVisibility = ANY, getterVisibility = NONE, setterVisibility = NONE)
    public static class TelemetryMixin {}
    

    Usage:

        ObjectMapper om = objectMapper.addMixIn(Telemetry.class, TelemetryMixin.class);
        Telemetry[] telemetries = om.readValue(someJson, Telemetry[].class);
    

    There is nothing that says you couldn't foreach any number of classes and apply the same mixin.

    If you're not familiar with mixins, they are conceptually simply: The structure of the mixin is super imposed on the target class (according to jackson, not as far as the JVM is concerned).

    0 讨论(0)
  • 2020-11-22 17:55

    If you use Spring Boot, you can configure Jackson globally as follows:

    import com.fasterxml.jackson.annotation.JsonAutoDetect;
    import com.fasterxml.jackson.annotation.PropertyAccessor;
    import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
    
    @Configuration
    public class JacksonObjectMapperConfiguration implements Jackson2ObjectMapperBuilderCustomizer {
    
        @Override
        public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
            jacksonObjectMapperBuilder.visibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
            jacksonObjectMapperBuilder.visibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
            jacksonObjectMapperBuilder.visibility(PropertyAccessor.CREATOR, JsonAutoDetect.Visibility.ANY);
        }
    
    }
    
    
    0 讨论(0)
提交回复
热议问题