Search code examples
spring-bootjacksonjson-deserializationjackson-databindjsonnullable

What is the proper way to customize deserialization process for JsonNullable of particular type


I want to customize JsonNullable<Boolean> deserialization process. So I've found the class JsonNullableDeserializer :

I've implemented my own deserializer:

public class MyJsonNullableDeserializer extends JsonNullableDeserializer {

    private static final long serialVersionUID = 1L;

    private boolean isBooleanDeserializer = false;
  
    public JsonNullableDeserializer(JavaType fullType, ValueInstantiator inst,
                                    TypeDeserializer typeDeser, JsonDeserializer<?> deser) {
          ....
        }
    }

    @Override
    public JsonNullable<Object> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        JsonToken t = p.getCurrentToken();
        if (t == JsonToken.VALUE_STRING && isBooleanDeserializer && p.getText().trim().isEmpty() ) {
          throw new IllegaArgumentException("....");
        }
        return super.deserialize(p, ctxt);
    }

Now I want to register MyJsonNullableDeserializer and I don't know how.

I see the class JsonNullableDeserializers

public class JsonNullableDeserializers extends Deserializers.Base {

    @Override
    public JsonDeserializer<?> findReferenceDeserializer(ReferenceType refType,
                                                         DeserializationConfig config, BeanDescription beanDesc,
                                                         TypeDeserializer contentTypeDeserializer, JsonDeserializer<?> contentDeserializer) {
        return (refType.hasRawClass(JsonNullable.class)) ? new JsonNullableDeserializer(refType, null, contentTypeDeserializer,contentDeserializer) : null;
    }
}

Looks like I have to replace

JsonNullableDeserializer with MyJsonNullableDeserializer somehow

I have no idea how to replace it. Could you please help ?


Solution

  • I think objectmapper is the place where we register our json deserializers. If I am wrong I can update the answer later. Below is the jackson configuration.

    @Configuration
    public class JacksonConfig {
    
        @Bean
        public Module jsonNullableBooleanModule() {
            SimpleModule module = new SimpleModule();
            module.addDeserializer(JsonNullable.class, new CustomBooleanJsonNullableDeserializer());
            return module;
        }
    }
    

    and for registration use below class

    @Configuration
    public class ObjectMapperConfig {
    
        @Bean
        @Primary
        public ObjectMapper objectMapper(com.fasterxml.jackson.databind.Module jsonNullableBooleanModule) {
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.registerModule(jsonNullableBooleanModule);
            return objectMapper;
        }
    }
    

    Here is working example.