在 Spring 环境中配置 Jackson 的 DeserializationProblemHandler

Configure a Jackson's DeserializationProblemHandler in Spring environment

据我了解,Spring 已经为 Jackson ObjectMapper 提供了一个 bean。因此,我没有创建新的 bean,而是尝试自定义这个 bean。

从这个 blog post, and then this Github project 我使用 Jackson2ObjectMapperBuilder bean 来实现这个定制。

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

然后,我试图自定义反序列化器以使其宽松:如果在反序列化 属性 时引发异常,我希望结果对象的 属性 为 null 并让反序列化继续(默认是在第一个无法反序列化的 属性 上失败)。

我已经能够通过扩展 DeserializationProblemHandler 的 class NullableFieldsDeserializationProblemHandler 实现这一点(我认为代码不相关,但如果需要,我可以分享) .

注册此处理程序的最简单方法是使用 ObjectMapper.addHandler() 方法。但是当然,这样做,我需要在每次注入和使用 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(),但我不知道如何使用它。

注意 我也尝试过 Jackson2ObjectMapperBuilderCustomizer 因为我正在使用 Spring 启动但没有更好的结果。

像这样写一个bean怎么样:

@Configuration
public class ObjectMapperConfiguration {

    @Bean
    ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        // jackson 1.9 and before
        objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); 
        // or jackson 2.0
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        return objectMapper;
    }
}

这是全局配置。相反,如果您想为特定的 class 配置功能,请在 class 定义上方使用此注释:

@JsonIgnoreProperties(ignoreUnknown = true)

无法通过 Jackson2ObjectMapperBuilderJackson2ObjectMapperBuilderCustomizer 直接将 DeserializationProblemHandler 添加到 ObjectMapperhandlerInstanciator() 方法用于其他用途。

但是,可以通过注册 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());
    } 
}