Skip to content

Commit 93ae71c

Browse files
committed
Switch Jackson write-dates-as-timestamps default
Update `JacksonAutoConfiguration` so that `write-dates-as-timestamps` now defaults to `false`. Fixes gh-11079
1 parent 78dee30 commit 93ae71c

File tree

2 files changed

+36
-8
lines changed

2 files changed

+36
-8
lines changed

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

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,18 @@
2020
import java.text.DateFormat;
2121
import java.text.SimpleDateFormat;
2222
import java.util.Collection;
23+
import java.util.Collections;
24+
import java.util.HashMap;
2325
import java.util.List;
2426
import java.util.Locale;
2527
import java.util.Map;
26-
import java.util.Map.Entry;
2728
import java.util.TimeZone;
2829

2930
import com.fasterxml.jackson.annotation.JsonCreator;
3031
import com.fasterxml.jackson.databind.Module;
3132
import com.fasterxml.jackson.databind.ObjectMapper;
3233
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
34+
import com.fasterxml.jackson.databind.SerializationFeature;
3335
import com.fasterxml.jackson.databind.module.SimpleModule;
3436
import com.fasterxml.jackson.datatype.joda.cfg.JacksonJodaDateFormat;
3537
import com.fasterxml.jackson.datatype.joda.ser.DateTimeSerializer;
@@ -70,12 +72,21 @@
7072
* @author Marcel Overdijk
7173
* @author Sebastien Deleuze
7274
* @author Johannes Edmeier
75+
* @author Phillip Webb
7376
* @since 1.1.0
7477
*/
7578
@Configuration
7679
@ConditionalOnClass(ObjectMapper.class)
7780
public class JacksonAutoConfiguration {
7881

82+
private static final Map<?, Boolean> FEATURE_DEFAULTS;
83+
84+
static {
85+
Map<Object, Boolean> featureDefaults = new HashMap<>();
86+
featureDefaults.put(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
87+
FEATURE_DEFAULTS = Collections.unmodifiableMap(featureDefaults);
88+
}
89+
7990
@Bean
8091
public JsonComponentModule jsonComponentModule() {
8192
return new JsonComponentModule();
@@ -228,6 +239,7 @@ public void customize(Jackson2ObjectMapperBuilder builder) {
228239
if (this.jacksonProperties.getTimeZone() != null) {
229240
builder.timeZone(this.jacksonProperties.getTimeZone());
230241
}
242+
configureFeatures(builder, FEATURE_DEFAULTS);
231243
configureFeatures(builder, this.jacksonProperties.getDeserialization());
232244
configureFeatures(builder, this.jacksonProperties.getSerialization());
233245
configureFeatures(builder, this.jacksonProperties.getMapper());
@@ -241,14 +253,16 @@ public void customize(Jackson2ObjectMapperBuilder builder) {
241253

242254
private void configureFeatures(Jackson2ObjectMapperBuilder builder,
243255
Map<?, Boolean> features) {
244-
for (Entry<?, Boolean> entry : features.entrySet()) {
245-
if (entry.getValue() != null && entry.getValue()) {
246-
builder.featuresToEnable(entry.getKey());
247-
}
248-
else {
249-
builder.featuresToDisable(entry.getKey());
256+
features.forEach((feature, value) -> {
257+
if (value != null) {
258+
if (value) {
259+
builder.featuresToEnable(feature);
260+
}
261+
else {
262+
builder.featuresToDisable(feature);
263+
}
250264
}
251-
}
265+
});
252266
}
253267

254268
private void configureDateFormat(Jackson2ObjectMapperBuilder builder) {

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.util.Date;
2323
import java.util.HashSet;
2424
import java.util.Set;
25+
import java.util.TimeZone;
2526

2627
import com.fasterxml.jackson.annotation.JsonCreator;
2728
import com.fasterxml.jackson.annotation.JsonCreator.Mode;
@@ -42,6 +43,7 @@
4243
import com.fasterxml.jackson.databind.SerializerProvider;
4344
import com.fasterxml.jackson.databind.module.SimpleModule;
4445
import com.fasterxml.jackson.databind.util.StdDateFormat;
46+
import com.fasterxml.jackson.datatype.joda.cfg.FormatConfig;
4547
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
4648
import org.joda.time.DateTime;
4749
import org.joda.time.DateTimeZone;
@@ -448,6 +450,18 @@ public void customParameterNamesModuleCanBeConfigured() {
448450
ParameterNamesModuleConfig.class, JacksonAutoConfiguration.class);
449451
}
450452

453+
@Test
454+
public void writeDatesAsTimestampsDefault() throws Exception {
455+
this.context.register(JacksonAutoConfiguration.class);
456+
this.context.refresh();
457+
ObjectMapper mapper = this.context.getBean(ObjectMapper.class);
458+
DateTime dateTime = new DateTime(1988, 6, 25, 20, 30, DateTimeZone.UTC);
459+
String expected = FormatConfig.DEFAULT_DATETIME_PRINTER.rawFormatter()
460+
.withZone(DateTimeZone.forTimeZone(TimeZone.getTimeZone("UTC")))
461+
.print(dateTime);
462+
assertThat(mapper.writeValueAsString(dateTime)).isEqualTo("\"" + expected + "\"");
463+
}
464+
451465
private void assertParameterNamesModuleCreatorBinding(Mode expectedMode,
452466
Class<?>... configClasses) {
453467
this.context.register(configClasses);

0 commit comments

Comments
 (0)