diff --git a/README.md b/README.md index be49af4..07088ce 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,9 @@ assertEquals(JsonNullable.undefined(), mapper.readValue("{}", Pet.class) ``` +`JsonNullable` can also be used as a `@JsonCreator` constructor parameter. +An absent property is passed to the constructor as `JsonNullable.undefined()` rather than as `null`, so it stays distinguishable from an explicit `null`. + The `ValueExtractor` is registered automatically via Java Service loader mechanism. The example class above will validate as follows ```java // instantiate javax.validation.Validator @@ -89,6 +92,4 @@ assertEquals(1, validationResult.size()); ## Limitations -* Doesn't work when passed as a parameter to a `@JsonCreator` constructor (non present field gets deserialized as null instead of undefined). - But as JsonNullable is here to represent "optional" values, there shouldn't be a need to put it in a constructor. * Doesn't work with `@JsonUnwrapped`. diff --git a/src/test/java/org/openapitools/jackson/nullable/CreatorTest.java b/src/test/java/org/openapitools/jackson/nullable/CreatorTest.java index 186baae..46bc9fe 100644 --- a/src/test/java/org/openapitools/jackson/nullable/CreatorTest.java +++ b/src/test/java/org/openapitools/jackson/nullable/CreatorTest.java @@ -2,19 +2,16 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import static org.junit.jupiter.api.Assertions.*; -// TODO: fix JsonNullable in constructor annotated by JsonCreator -@Disabled("JsonNullable in a constructor is deserialized to JsonNullable[null] instead of JsonNullable.undefined") class CreatorTest extends ModuleTestBase { static class CreatorWithJsonNullableStrings { JsonNullable a, b; - // note: something weird with test setup, should not need annotations + // note: parameter names are not retained by default, hence the explicit @JsonProperty @JsonCreator public CreatorWithJsonNullableStrings(@JsonProperty("a") JsonNullable a, @JsonProperty("b") JsonNullable b) { @@ -45,5 +42,21 @@ void testCreatorWithJsonNullable(JsonProcessor jsonProcessor) throws Exception { assertTrue(bean.a.isPresent()); assertFalse(bean.b.isPresent()); assertEquals("foo", bean.a.get()); + assertEquals(JsonNullable.undefined(), bean.b); } -} \ No newline at end of file + + /** + * An absent creator property has to stay distinguishable from one that is + * explicitly set to null, which is the reason JsonNullable exists. + */ + @ParameterizedTest + @MethodSource("jsonProcessors") + void testCreatorSeparatesExplicitNullFromAbsent(JsonProcessor jsonProcessor) throws Exception { + jsonProcessor.mapperWithModule(); + CreatorWithJsonNullableStrings bean = jsonProcessor.readValue( + aposToQuotes("{'a':null}"), CreatorWithJsonNullableStrings.class); + assertNotNull(bean); + assertEquals(JsonNullable.of(null), bean.a); + assertEquals(JsonNullable.undefined(), bean.b); + } +}