From f4788015e30aca2442b40d1dad39ef5e2f19d25a Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Wed, 5 Feb 2025 16:14:44 -0800 Subject: [PATCH] Fix #355 (#356) --- .../ser/JSR310FormattedSerializerBase.java | 8 ++++- .../datatype/jsr310/ser/YearSerializer.java | 7 ++++ .../datatype/jsr310/ser/YearSerTest.java | 32 +++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/datetime/src/main/java/tools/jackson/datatype/jsr310/ser/JSR310FormattedSerializerBase.java b/datetime/src/main/java/tools/jackson/datatype/jsr310/ser/JSR310FormattedSerializerBase.java index c4990f40..23277948 100644 --- a/datetime/src/main/java/tools/jackson/datatype/jsr310/ser/JSR310FormattedSerializerBase.java +++ b/datetime/src/main/java/tools/jackson/datatype/jsr310/ser/JSR310FormattedSerializerBase.java @@ -207,7 +207,13 @@ protected boolean useTimestamp(SerializationContext ctxt) { } } // assume that explicit formatter definition implies use of textual format - return (_formatter == null) && (ctxt != null) && ctxt.isEnabled(getTimestampsFeature()); + return (_formatter == null) && useTimestampFromGlobalDefaults(ctxt); + } + + // @since 2.19 + protected boolean useTimestampFromGlobalDefaults(SerializationContext ctxt) { + return (ctxt != null) + && ctxt.isEnabled(getTimestampsFeature()); } protected boolean _useTimestampExplicitOnly(SerializationContext ctxt) { diff --git a/datetime/src/main/java/tools/jackson/datatype/jsr310/ser/YearSerializer.java b/datetime/src/main/java/tools/jackson/datatype/jsr310/ser/YearSerializer.java index 03a74f05..cf7e993d 100644 --- a/datetime/src/main/java/tools/jackson/datatype/jsr310/ser/YearSerializer.java +++ b/datetime/src/main/java/tools/jackson/datatype/jsr310/ser/YearSerializer.java @@ -58,6 +58,13 @@ protected YearSerializer withFormat(DateTimeFormatter dtf, return new YearSerializer(this, dtf, useTimestamp); } + // Need to ensure Year still defaults to numeric ("timestamp") regardless + // of general global setting (since that defaults to textual in Jackson 3.x) + @Override + protected boolean useTimestampFromGlobalDefaults(SerializationContext ctxt) { + return true; + } + @Override public void serialize(Year year, JsonGenerator generator, SerializationContext ctxt) throws JacksonException diff --git a/datetime/src/test/java/tools/jackson/datatype/jsr310/ser/YearSerTest.java b/datetime/src/test/java/tools/jackson/datatype/jsr310/ser/YearSerTest.java index 1f40a7f9..82e56529 100644 --- a/datetime/src/test/java/tools/jackson/datatype/jsr310/ser/YearSerTest.java +++ b/datetime/src/test/java/tools/jackson/datatype/jsr310/ser/YearSerTest.java @@ -21,6 +21,8 @@ import org.junit.jupiter.api.Test; +import com.fasterxml.jackson.annotation.JsonFormat; + import tools.jackson.databind.ObjectMapper; import tools.jackson.datatype.jsr310.MockObjectConfiguration; import tools.jackson.datatype.jsr310.ModuleTestBase; @@ -29,6 +31,17 @@ public class YearSerTest extends ModuleTestBase { + final static class YearAsStringWrapper { + @JsonFormat(shape = JsonFormat.Shape.STRING) + public Year value; + + public YearAsStringWrapper(Year value) { + this.value = value; + } + } + + // Defaults fine: year only serialized as String with explicit + // overrides private final ObjectMapper MAPPER = newMapper(); @Test @@ -40,6 +53,25 @@ public void testDefaultSerialization() throws Exception MAPPER.writeValueAsString(Year.of(2013))); } + @Test + public void testAsStringSerializationViaAnnotation() throws Exception + { + assertEquals(a2q("{'value':'1972'}"), + MAPPER.writeValueAsString(new YearAsStringWrapper(Year.of(1972)))); + } + + @Test + public void testAsStringSerializationViaFormatConfig() throws Exception + { + final ObjectMapper asStringMapper = mapperBuilder() + .withConfigOverride(Year.class, o -> o.setFormat( + JsonFormat.Value.forShape(JsonFormat.Shape.STRING))) + .build(); + + assertEquals(q("2025"), + asStringMapper.writeValueAsString(Year.of(2025))); + } + @Test public void testSerializationWithTypeInfo() throws Exception {