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