Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I tried to add custom problem handler to object mapper with Jackson2ObjectMapperBuilderCustomizer:

@Bean
public Jackson2ObjectMapperBuilderCustomizer customizer() {
    return new Jackson2ObjectMapperBuilderCustomizer() {
        @Override
        public void customize(Jackson2ObjectMapperBuilder builder) {
            ObjectMapper m = builder.build();
            m.addHandler(
                    new DeserializationProblemHandler() {
                        @Override
                        public boolean handleUnknownProperty(DeserializationContext ctxt, JsonParser p, JsonDeserializer<?> deserializer, Object beanOrClass, String propertyName) throws IOException {
                            System.out.println("ahahahaa");
                            return super.handleUnknownProperty(ctxt, p, deserializer, beanOrClass, propertyName);
                        }
                    }
            );
        }
    };
}

But when i autowired ObjectMapper bean _problemHandlers property is null.

I also tried just customize existed ObjectMapper with:

@Autowired
public customize(ObjectMapper mapper) {
...
}

But result is the same. I don't know who can erasure this property. I don't initialize another builders/factories/etc of object mapper in another place at all. What i'm doing wrong?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
221 views
Welcome To Ask or Share your Answers For Others

1 Answer

It's not possible to directly add a DeserializationProblemHandler to the ObjectMapper via a Jackson2ObjectMapperBuilder or Jackson2ObjectMapperBuilderCustomizer. Calling build() on the builder is a no-go, since the resulting ObjectMapper is local to the method: Spring itself will call build() later, creating another ObjectMapper instance.

However, it's possible to do so by registering a Jackson module :

  • the builder has a modules() method
  • the module has access via setupModule() to a SetupContext instance, which has a addDeserializationProblemHandler() method

This should then work

@Bean
public Jackson2ObjectMapperBuilderCustomizer customizer() {
    return new Jackson2ObjectMapperBuilderCustomizer() {
        @Override
        public void customize(Jackson2ObjectMapperBuilder builder) {
            builder.modules(new MyModule());
        }
    };
}

private static class MyModule extends SimpleModule {
    @Override
    public void setupModule(SetupContext context) {
        // Required, as documented in the Javadoc of SimpleModule
        super.setupModule(context);
        context.addDeserializationProblemHandler(new MyDeserializationProblemHandler());
    } 
}

private static class MyDeserializationProblemHandler extends DeserializationProblemHandler {
    @Override
    public boolean handleUnknownProperty(DeserializationContext ctxt,
                                         JsonParser p,
                                         JsonDeserializer<?> deserializer,
                                         Object beanOrClass,
                                         String propertyName)
            throws IOException {
        System.out.println("ahahahaa");
        return super.handleUnknownProperty(ctxt, p, deserializer, beanOrClass, propertyName);
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...