Explain Codes LogoExplain Codes Logo

How to specify jackson to only use fields - preferably globally

java
jackson-configuration
objectmapper
json-serialization
Alex KataevbyAlex Kataev·Aug 24, 2024
TLDR

To specify Jackson to use only fields globally, apply the following configuration to an ObjectMapper instance:

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

For a specific class, utilize @JsonAutoDetect to apply field visibility:

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) public class YourClass { // fields here }

Diving deeper: Additional configurations

Global visibility with ObjectMapper's wrapper

To apply the settings globally, especially in larger applications with numerous ObjectMapper instances, a viable strategy is to implement a wrapper around ObjectMapper:

public class ObjectMapperWrapper { private static final ObjectMapper MAPPER = new ObjectMapper(); static { MAPPER.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE); MAPPER.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); } public static ObjectMapper getMapper() { return MAPPER; // Pre-configured ObjectMapper: "one mapper to rule them all" 😉 } }

Handling getters/setters and creators

Occasionally, you might need to handle boolean getters (is... methods) too. Adjust their visibility this way:

mapper.setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE); mapper.setVisibility(PropertyAccessor.IS_GETTER, JsonAutoDetect.Visibility.NONE); mapper.setVisibility(PropertyAccessor.SETTER, JsonAutoDetect.Visibility.NONE); mapper.setVisibility(PropertyAccessor.CREATOR, JsonAutoDetect.Visibility.NONE); // Because constructors have feelings too!

Mixins for flexible field visibility

Mixins provide a powerful way to apply annotations without messing with existing class source codes. A global field visibility mixin looks like this:

public interface FieldVisibilityMixin { @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) } mapper.addMixIn(Object.class, FieldVisibilityMixin.class); // Mixin magic!

Now, field visibility is globally set to ANY for every class visited by Jackson.

Tactical application: When and where

Classroom level teaching: Annotating specific classes

For certain classes, you may need to override the global rules. Use @JsonAutoDetect at class-level:

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.NONE) // "None of your fields are mine!" said Jackson🕵️‍♀️ public class AnnotatedClass { // fields ignored in serialization }

Spring Boot configuration

If you're working with Spring Boot, you can externalize these settings:

spring.jackson.visibility.field=ANY spring.jackson.visibility.getter=NONE spring.jackson.visibility.is-getter=NONE spring.jackson.visibility.setter=NONE spring.jackson.visibility.creator=NONE

This grants easy manageability across various environments.

Caveats and considerations

These methods allow efficient serialization, but are not universal solutions. Applications that require intricate JSON structure control, or maintaining backward compatibility, may require additional customizations.