mirror of
https://github.com/spring-projects/spring-boot.git
synced 2026-10-10 03:19:01 +00:00
Add property to configure Jackson 3 with Boot's Jackson 2 defaults
Closes gh-
This commit is contained in:
@@ -104,6 +104,8 @@ Note that, thanks to the use of xref:reference:features/external-config.adoc#fea
|
||||
|
||||
This environment-based configuration is applied to the auto-configured javadoc:tools.jackson.databind.json.JsonMapper.Builder[] bean and applies to any mappers created by using the builder, including the auto-configured javadoc:tools.jackson.databind.json.JsonMapper[] bean.
|
||||
|
||||
To ease the migration when working on an application that previously used Jackson 2, the auto-configured `JsonMapper` can be configured to use defaults that are as close as possible to those that Spring Boot used for Jackson 2. To enable these defaults, set configprop:spring.jackson.use-jackson2-defaults[] to `true`.
|
||||
|
||||
The context's javadoc:tools.jackson.databind.json.JsonMapper.Builder[] can be customized by one or more javadoc:org.springframework.boot.jackson.autoconfigure.JsonMapperBuilderCustomizer[] beans.
|
||||
Such customizer beans can be ordered (Boot's own customizer has an order of 0), letting additional customization be applied both before and after Boot's customization.
|
||||
|
||||
|
||||
+6
@@ -36,6 +36,7 @@ import tools.jackson.databind.ObjectMapper;
|
||||
import tools.jackson.databind.PropertyNamingStrategies;
|
||||
import tools.jackson.databind.PropertyNamingStrategy;
|
||||
import tools.jackson.databind.cfg.ConstructorDetector;
|
||||
import tools.jackson.databind.cfg.DateTimeFeature;
|
||||
import tools.jackson.databind.json.JsonMapper;
|
||||
|
||||
import org.springframework.aot.hint.ReflectionHints;
|
||||
@@ -164,6 +165,11 @@ public final class JacksonAutoConfiguration {
|
||||
|
||||
@Override
|
||||
public void customize(JsonMapper.Builder builder) {
|
||||
if (this.jacksonProperties.isUseJackson2Defaults()) {
|
||||
builder.configureForJackson2()
|
||||
.disable(DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS,
|
||||
DateTimeFeature.WRITE_DURATIONS_AS_TIMESTAMPS);
|
||||
}
|
||||
if (this.jacksonProperties.getDefaultPropertyInclusion() != null) {
|
||||
builder.changeDefaultPropertyInclusion((handler) -> handler
|
||||
.withValueInclusion(this.jacksonProperties.getDefaultPropertyInclusion()));
|
||||
|
||||
+14
@@ -109,6 +109,12 @@ public class JacksonProperties {
|
||||
*/
|
||||
private @Nullable Locale locale;
|
||||
|
||||
/**
|
||||
* Whether to configure Jackson 3 with the same defaults as Spring Boot previously
|
||||
* used for Jackson 2.
|
||||
*/
|
||||
private boolean useJackson2Defaults = false;
|
||||
|
||||
private final Datatype datatype = new Datatype();
|
||||
|
||||
private final Json json = new Json();
|
||||
@@ -185,6 +191,14 @@ public class JacksonProperties {
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
public boolean isUseJackson2Defaults() {
|
||||
return this.useJackson2Defaults;
|
||||
}
|
||||
|
||||
public void setUseJackson2Defaults(boolean useJackson2Defaults) {
|
||||
this.useJackson2Defaults = useJackson2Defaults;
|
||||
}
|
||||
|
||||
public Datatype getDatatype() {
|
||||
return this.datatype;
|
||||
}
|
||||
|
||||
+52
@@ -29,6 +29,8 @@ import org.assertj.core.api.InstanceOfAssertFactories;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import tools.jackson.core.JsonGenerator;
|
||||
import tools.jackson.core.StreamReadFeature;
|
||||
import tools.jackson.core.StreamWriteFeature;
|
||||
import tools.jackson.core.json.JsonReadFeature;
|
||||
import tools.jackson.core.json.JsonWriteFeature;
|
||||
import tools.jackson.databind.DeserializationFeature;
|
||||
@@ -539,6 +541,56 @@ class JacksonAutoConfigurationTests {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingJackson2DefaultsShouldBeConfiguredUsingConfigureForJackson2() {
|
||||
this.contextRunner.withPropertyValues("spring.jackson.use-jackson2-defaults=true").run((context) -> {
|
||||
JsonMapper jsonMapper = context.getBean(JsonMapper.class);
|
||||
JsonMapper jackson2ConfiguredJsonMapper = JsonMapper.builder().configureForJackson2().build();
|
||||
for (DateTimeFeature feature : DateTimeFeature.values()) {
|
||||
boolean expected = (feature == DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS
|
||||
|| feature == DateTimeFeature.WRITE_DURATIONS_AS_TIMESTAMPS) ? false
|
||||
: jackson2ConfiguredJsonMapper.isEnabled(feature);
|
||||
assertThat(jsonMapper.isEnabled(feature)).as(feature.name()).isEqualTo(expected);
|
||||
}
|
||||
for (DeserializationFeature feature : DeserializationFeature.values()) {
|
||||
assertThat(jsonMapper.isEnabled(feature)).as(feature.name())
|
||||
.isEqualTo(jackson2ConfiguredJsonMapper.isEnabled(feature));
|
||||
}
|
||||
for (EnumFeature feature : EnumFeature.values()) {
|
||||
assertThat(jsonMapper.isEnabled(feature)).as(feature.name())
|
||||
.isEqualTo(jackson2ConfiguredJsonMapper.isEnabled(feature));
|
||||
}
|
||||
for (JsonNodeFeature feature : JsonNodeFeature.values()) {
|
||||
assertThat(jsonMapper.isEnabled(feature)).as(feature.name())
|
||||
.isEqualTo(jackson2ConfiguredJsonMapper.isEnabled(feature));
|
||||
}
|
||||
for (JsonReadFeature feature : JsonReadFeature.values()) {
|
||||
assertThat(jsonMapper.isEnabled(feature)).as(feature.name())
|
||||
.isEqualTo(jackson2ConfiguredJsonMapper.isEnabled(feature));
|
||||
}
|
||||
for (JsonWriteFeature feature : JsonWriteFeature.values()) {
|
||||
assertThat(jsonMapper.isEnabled(feature)).as(feature.name())
|
||||
.isEqualTo(jackson2ConfiguredJsonMapper.isEnabled(feature));
|
||||
}
|
||||
for (MapperFeature feature : MapperFeature.values()) {
|
||||
assertThat(jsonMapper.isEnabled(feature)).as(feature.name())
|
||||
.isEqualTo(jackson2ConfiguredJsonMapper.isEnabled(feature));
|
||||
}
|
||||
for (SerializationFeature feature : SerializationFeature.values()) {
|
||||
assertThat(jsonMapper.isEnabled(feature)).as(feature.name())
|
||||
.isEqualTo(jackson2ConfiguredJsonMapper.isEnabled(feature));
|
||||
}
|
||||
for (StreamReadFeature feature : StreamReadFeature.values()) {
|
||||
assertThat(jsonMapper.isEnabled(feature)).as(feature.name())
|
||||
.isEqualTo(jackson2ConfiguredJsonMapper.isEnabled(feature));
|
||||
}
|
||||
for (StreamWriteFeature feature : StreamWriteFeature.values()) {
|
||||
assertThat(jsonMapper.isEnabled(feature)).as(feature.name())
|
||||
.isEqualTo(jackson2ConfiguredJsonMapper.isEnabled(feature));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static class MyDateFormat extends SimpleDateFormat {
|
||||
|
||||
MyDateFormat() {
|
||||
|
||||
Reference in New Issue
Block a user