Browse Source

Move jackson read and write to spring.jackson.json

The spring.jackson.read and spring.jackson.write properties are
JSON-specific. To make this more clear, this commit moves them
beneath spring.jackson.json. This also paves the way for
spring.jackson.cbor and spring.jackson.xml properties for CBOR- and
XML-specific settings should we add auto-configuration for XMLMapper
and/or CBORMapper in the future.

Closes gh-47328
pull/47334/head
Andy Wilkinson 3 months ago
parent
commit
0959271061
  1. 22
      documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/spring-mvc.adoc
  2. 4
      module/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/JacksonAutoConfiguration.java
  3. 46
      module/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/JacksonProperties.java
  4. 20
      module/spring-boot-jackson/src/main/resources/META-INF/additional-spring-configuration-metadata.json
  5. 21
      module/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/autoconfigure/JacksonAutoConfigurationTests.java

22
documentation/spring-boot-docs/src/docs/antora/modules/how-to/pages/spring-mvc.adoc

@ -74,31 +74,31 @@ These features are described in several enums (in Jackson) that map onto propert @@ -74,31 +74,31 @@ These features are described in several enums (in Jackson) that map onto propert
| `spring.jackson.datatype.json-node.<feature_name>`
| `true`, `false`
| javadoc:com.fasterxml.jackson.annotation.JsonInclude$Include[]
| configprop:spring.jackson.default-property-inclusion[]
| `always`, `non_null`, `non_absent`, `non_default`, `non_empty`
|===
| javadoc:tools.jackson.databind.DeserializationFeature[]
| `spring.jackson.deserialization.<feature_name>`
| `true`, `false`
| javadoc:tools.jackson.databind.MapperFeature[]
| `spring.jackson.mapper.<feature_name>`
| `true`, `false`
| javadoc:tools.jackson.core.JsonReadFeature[]
| `spring.jackson.read.<feature_name>`
| `spring.jackson.json.read.<feature_name>`
| `true`, `false`
| javadoc:tools.jackson.core.JsonWriteFeature[]
| `spring.jackson.write.<feature_name>`
| `spring.jackson.json.write.<feature_name>`
| `true`, `false`
| javadoc:tools.jackson.databind.MapperFeature[]
| `spring.jackson.mapper.<feature_name>`
| `true`, `false`
| javadoc:tools.jackson.databind.SerializationFeature[]
| `spring.jackson.serialization.<feature_name>`
| `true`, `false`
| javadoc:com.fasterxml.jackson.annotation.JsonInclude$Include[]
| configprop:spring.jackson.default-property-inclusion[]
| `always`, `non_null`, `non_absent`, `non_default`, `non_empty`
|===
For example, to enable pretty print, set `spring.jackson.serialization.indent_output=true`.
Note that, thanks to the use of xref:reference:features/external-config.adoc#features.external-config.typesafe-configuration-properties.relaxed-binding[relaxed binding], the case of `indent_output` does not have to match the case of the corresponding enum constant, which is `INDENT_OUTPUT`.

4
module/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/JacksonAutoConfiguration.java

@ -175,8 +175,8 @@ public final class JacksonAutoConfiguration { @@ -175,8 +175,8 @@ public final class JacksonAutoConfiguration {
configureFeatures(builder, this.jacksonProperties.getDeserialization(), builder::configure);
configureFeatures(builder, this.jacksonProperties.getSerialization(), builder::configure);
configureFeatures(builder, this.jacksonProperties.getMapper(), builder::configure);
configureFeatures(builder, this.jacksonProperties.getRead(), builder::configure);
configureFeatures(builder, this.jacksonProperties.getWrite(), builder::configure);
configureFeatures(builder, this.jacksonProperties.getJson().getRead(), builder::configure);
configureFeatures(builder, this.jacksonProperties.getJson().getWrite(), builder::configure);
configureFeatures(builder, this.jacksonProperties.getDatatype().getDatetime(), builder::configure);
configureFeatures(builder, this.jacksonProperties.getDatatype().getEnum(), builder::configure);
configureFeatures(builder, this.jacksonProperties.getDatatype().getJsonNode(), builder::configure);

46
module/spring-boot-jackson/src/main/java/org/springframework/boot/jackson/autoconfigure/JacksonProperties.java

@ -81,16 +81,6 @@ public class JacksonProperties { @@ -81,16 +81,6 @@ public class JacksonProperties {
*/
private final Map<MapperFeature, Boolean> mapper = new EnumMap<>(MapperFeature.class);
/**
* Jackson on/off features for readers.
*/
private final Map<JsonReadFeature, Boolean> read = new EnumMap<>(JsonReadFeature.class);
/**
* Jackson on/off features for writers.
*/
private final Map<JsonWriteFeature, Boolean> write = new EnumMap<>(JsonWriteFeature.class);
/**
* Controls the inclusion of properties during serialization. Configured with one of
* the values in Jackson's JsonInclude.Include enumeration.
@ -121,6 +111,8 @@ public class JacksonProperties { @@ -121,6 +111,8 @@ public class JacksonProperties {
private final Datatype datatype = new Datatype();
private final Json json = new Json();
public @Nullable String getDateFormat() {
return this.dateFormat;
}
@ -153,14 +145,6 @@ public class JacksonProperties { @@ -153,14 +145,6 @@ public class JacksonProperties {
return this.mapper;
}
public Map<JsonReadFeature, Boolean> getRead() {
return this.read;
}
public Map<JsonWriteFeature, Boolean> getWrite() {
return this.write;
}
public JsonInclude.@Nullable Include getDefaultPropertyInclusion() {
return this.defaultPropertyInclusion;
}
@ -205,6 +189,10 @@ public class JacksonProperties { @@ -205,6 +189,10 @@ public class JacksonProperties {
return this.datatype;
}
public Json getJson() {
return this.json;
}
public enum ConstructorDetectorStrategy {
/**
@ -261,4 +249,26 @@ public class JacksonProperties { @@ -261,4 +249,26 @@ public class JacksonProperties {
}
public static class Json {
/**
* Jackson on/off token reader features that are specific to JSON.
*/
private final Map<JsonReadFeature, Boolean> read = new EnumMap<>(JsonReadFeature.class);
/**
* Jackson on/off token writer features that are specific to JSON.
*/
private final Map<JsonWriteFeature, Boolean> write = new EnumMap<>(JsonWriteFeature.class);
public Map<JsonReadFeature, Boolean> getRead() {
return this.read;
}
public Map<JsonWriteFeature, Boolean> getWrite() {
return this.write;
}
}
}

20
module/spring-boot-jackson/src/main/resources/META-INF/additional-spring-configuration-metadata.json

@ -15,6 +15,26 @@ @@ -15,6 +15,26 @@
"deprecation": {
"level": "error"
}
},
{
"name": "spring.jackson.read",
"type": "java.util.Map<tools.jackson.core.json.JsonReadFeature,java.lang.Boolean>",
"description": "Jackson on/off token reader features that are specific to JSON.",
"sourceType": "org.springframework.boot.jackson.autoconfigure.JacksonProperties",
"deprecation": {
"level": "error",
"replacement": "spring.jackson.json.read"
}
},
{
"name": "spring.jackson.write",
"type": "java.util.Map<tools.jackson.core.json.JsonWriteFeature,java.lang.Boolean>",
"description": "Jackson on/off token writer features that are specific to JSON.",
"sourceType": "org.springframework.boot.jackson.autoconfigure.JacksonProperties",
"deprecation": {
"level": "error",
"replacement": "spring.jackson.json.write"
}
}
]
}

21
module/spring-boot-jackson/src/test/java/org/springframework/boot/jackson/autoconfigure/JacksonAutoConfigurationTests.java

@ -237,8 +237,8 @@ class JacksonAutoConfigurationTests { @@ -237,8 +237,8 @@ class JacksonAutoConfigurationTests {
}
@Test
void enableReadFeature() {
this.contextRunner.withPropertyValues("spring.jackson.read.allow_single_quotes:true").run((context) -> {
void enableJsonReadFeature() {
this.contextRunner.withPropertyValues("spring.jackson.json.read.allow_single_quotes:true").run((context) -> {
JsonMapper mapper = context.getBean(JsonMapper.class);
assertThat(JsonReadFeature.ALLOW_SINGLE_QUOTES.enabledByDefault()).isFalse();
assertThat(mapper.isEnabled(JsonReadFeature.ALLOW_SINGLE_QUOTES)).isTrue();
@ -246,18 +246,19 @@ class JacksonAutoConfigurationTests { @@ -246,18 +246,19 @@ class JacksonAutoConfigurationTests {
}
@Test
void enableWriteFeature() {
this.contextRunner.withPropertyValues("spring.jackson.write.write_numbers_as_strings:true").run((context) -> {
JsonMapper mapper = context.getBean(JsonMapper.class);
JsonWriteFeature feature = JsonWriteFeature.WRITE_NUMBERS_AS_STRINGS;
assertThat(feature.enabledByDefault()).isFalse();
assertThat(mapper.isEnabled(feature)).isTrue();
});
void enableJsonWriteFeature() {
this.contextRunner.withPropertyValues("spring.jackson.json.write.write_numbers_as_strings:true")
.run((context) -> {
JsonMapper mapper = context.getBean(JsonMapper.class);
JsonWriteFeature feature = JsonWriteFeature.WRITE_NUMBERS_AS_STRINGS;
assertThat(feature.enabledByDefault()).isFalse();
assertThat(mapper.isEnabled(feature)).isTrue();
});
}
@Test
void disableWriteFeature() {
this.contextRunner.withPropertyValues("spring.jackson.write.write_hex_upper_case:false").run((context) -> {
this.contextRunner.withPropertyValues("spring.jackson.json.write.write_hex_upper_case:false").run((context) -> {
JsonMapper mapper = context.getBean(JsonMapper.class);
assertThat(JsonWriteFeature.WRITE_HEX_UPPER_CASE.enabledByDefault()).isTrue();
assertThat(mapper.isEnabled(JsonWriteFeature.WRITE_HEX_UPPER_CASE)).isFalse();

Loading…
Cancel
Save