- Notifications
You must be signed in to change notification settings - Fork0
JsonNullable wrapper class and Jackson module to support meaningful null values
License
kd656/jackson-databind-nullable
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
This module provides aJsonNullable wrapper class and a Jackson module to serialize/deserialize it.TheJsonNullable wrapper shall be used to wrap Java bean fields for which it is important to distinguish between an explicit"null" and the field not being present.A typical usage is when implementingJson Merge Patch where an explicit"null"has the meaning "set this field to null / remove this field" whereas a non-present field has the meaning "don't change the value of this field".
The module comes with an integratedValueExtractor that automatically unwraps the contained value of theJsonNullable if used together with javax.validation Bean validation (JSR 380).
Note : a lot of people useOptional to bring this behavior.Although it kinda works, it's not a good idea because:
- Beans shouldn't have
Optionalfields.Optionalwas designed to be used only as method return value. Optionalshould never be null.The goal ofOptionalis to wrap thenulland prevent NPE so the code should be designed to never assignnullto anOptional.A code invoking a method returning an Optional should be confident that this Optional is not null.
The module is compatible with JDK8+
./mvnw clean installJsonNullable shall primarily be used in bean fields.
If we have the following class
publicstaticclassPet {@Size(max =10)publicJsonNullable<String>name =JsonNullable.undefined();publicPetname(JsonNullable<String>name) {this.name =name;returnthis; }}
And we instantiate the mapper either for JSON
importcom.fasterxml.jackson.databind.ObjectMapper;// ...ObjectMappermapper =newObjectMapper();mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);mapper.registerModule(newJsonNullableModule());
or for XML
importcom.fasterxml.jackson.dataformat.xml.XmlMapper;// ...XmlMapperxmlMapper =newXmlMapper();xmlMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);xmlMapper.registerModule(newJsonNullableModule());
Then we can serialize
assertEquals("{}",mapper.writeValueAsString(newPet().name(JsonNullable.<String>undefined())));assertEquals("{\"name\":null}",mapper.writeValueAsString(newPet().name(JsonNullable.<String>of(null))));assertEquals("{\"name\":\"Rex\"}",mapper.writeValueAsString(newPet().name(JsonNullable.of("Rex"))));
and deserialize
assertEquals(JsonNullable.of("Rex"),mapper.readValue("{\"name\":\"Rex\"}",Pet.class).name);assertEquals(JsonNullable.<String>of(null),mapper.readValue("{\"name\":null}",Pet.class).name);assertEquals(JsonNullable.<String>undefined(),mapper.readValue("{}",Pet.class).name);
TheValueExtractor is registered automatically via Java Service loader mechanism. The example class above will validate as follows
// instantiate javax.validation.ValidatorValidatorvalidator =Validation.buildDefaultValidatorFactory().getValidator();PetmyPet =newPet().name(JsonNullable.of("My Pet's really long name"));Set<ConstraintViolation<Pet>>validationResult =validator.validate(myPet);assertTrue(1,validationResult.size());
- Doesn't work when passed as a parameter to a
@JsonCreatorconstructor (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.
About
JsonNullable wrapper class and Jackson module to support meaningful null values
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Releases
Packages0
Languages
- Java100.0%