小编典典

在Spring环境中配置Jackson的DeserializationProblemHandler

spring-boot

据我了解,Spring已经为Jackson提供了一个bean ObjectMapper。因此,我试图自定义该bean,而不是创建一个新bean。

从这篇博客文章到这个Github项目,我使用Jackson2ObjectMapperBuilderbean实现了这种定制。

@Bean
public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder(ApplicationContext context) {
    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
    builder.findModulesViaServiceLoader(true);
    return builder;
}

然后,我试图自定义反序列化器以使其宽大:如果反序列化属性时引发异常,则我希望结果对象的属性为null并且让反序列化继续进行(默认是对不能反序列化)。

我已经能够通过NullableFieldsDeserializationProblemHandler扩展类来实现这一点DeserializationProblemHandler(我认为代码不相关,但是如果需要,我可以共享它)。

注册此处理程序的最简单方法是使用的.addHandler()方法ObjectMapper。但是当然,这样做的话,我每次注入和使用时都需要进行设置ObjectMapper。我希望能够配置处理程序,以便每次ObjectMapper自动连线时,该处理程序就已经存在。

到目前为止,我想到的最好的解决方案是@PostConstruct仅使用注释来注册问题处理程序。

@Configuration
public class JacksonConfiguration implements InitializingBean {

  @Autowired private ObjectMapper objectMapper;

  @Bean
  public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder(ApplicationContext context) {
    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
    builder.findModulesViaServiceLoader(true);
    return builder;
  }

  @Override
  public void afterPropertiesSet() {
    objectMapper.addHandler(new NullableFieldsDeserializationProblemHandler());
  }
}

但是此解决方案的问题在于,看来我仍然可以访问ObjectMapper尚未注册问题处理程序的自动装配(在调试模式下需要它时,我可以看到它发生了)。

知道如何注册该处理程序吗?我注意到Jackson2ObjectMapperBuilder有一个,.handlerInstantiator()但我不知道如何使用它。

注意 ,由于我使用的是Spring
Boot,所以我也尝试过Jackson2ObjectMapperBuilderCustomizer,但效果没有更好。


阅读 1130

收藏
2020-05-30

共1个答案

小编典典

无法通过或直接将a添加DeserializationProblemHandler到。该方法用于其他方面。ObjectMapper``Jackson2ObjectMapperBuilder``Jackson2ObjectMapperBuilderCustomizer``handlerInstanciator()

但是,可以通过注册Jackson模块来做到这一点:

  • 建造者有一种modules()方法
  • 该模块可通过实例访问setupModule(),该SetupContext实例具有一个addDeserializationProblemHandler()方法

这有效:

@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 NullableFieldsDeserializationProblemHandler());
    } 
}
2020-05-30