[java] How to specify jackson to only use fields - preferably globally

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 canonical source of serialization config and thus don't want jackson to look at properties at all.

I can do this on an individual class basis with the annotation:

 @JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)

But I don't want to have to put this on every single class...

Is it possible to configure this globally? Like add some to the Object Mapper?

This question is related to java json jackson

The answer is


Specifically for boolean is*() getters:

I've spend a lot of time on why neither below

  @JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)

nor this

  setVisibility(PropertyAccessor.SETTER, JsonAutoDetect.Visibility.NONE);
  setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE);
  setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);

worked for my Boolean Getter/Setter.

Solution is simple:

  @JsonAutoDetect(isGetterVisibility = Visibility.NONE, ...          
  setVisibility(PropertyAccessor.IS_GETTER, JsonAutoDetect.Visibility.NONE);

UPDATE: spring-boot allowed configure it:

jackson:
  visibility.field: any
  visibility.getter: none
  visibility.setter: none
  visibility.is-getter: none

See Common application properties # JACKSON


In Jackson 2.0 and later you can simply use:

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;   

...

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

to turn off autodetection.


@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();

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);
    }

}


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


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).


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.


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to json

Use NSInteger as array index Uncaught SyntaxError: Unexpected end of JSON input at JSON.parse (<anonymous>) HTTP POST with Json on Body - Flutter/Dart Importing json file in TypeScript json.decoder.JSONDecodeError: Extra data: line 2 column 1 (char 190) Angular 5 Service to read local .json file How to import JSON File into a TypeScript file? Use Async/Await with Axios in React.js Uncaught SyntaxError: Unexpected token u in JSON at position 0 how to remove json object key and value.?

Examples related to jackson

No Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator JSON parse error: Can not construct instance of java.time.LocalDate: no String-argument constructor/factory method to deserialize from String value How to convert JSON string into List of Java object? Deserialize Java 8 LocalDateTime with JacksonMapper java.lang.IllegalArgumentException: No converter found for return value of type java.lang.ClassNotFoundException: com.fasterxml.jackson.annotation.JsonInclude$Value How to modify JsonNode in Java? Deserialize JSON with Jackson into Polymorphic Types - A Complete Example is giving me a compile error Convert Map to JSON using Jackson Required request body content is missing: org.springframework.web.method.HandlerMethod$HandlerMethodParameter