在Spring环境中配置Jackson的DeserializationProblemHandler [英] Configure a Jackson's DeserializationProblemHandler in Spring environment

查看:254
本文介绍了在Spring环境中配置Jackson的DeserializationProblemHandler的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我了解,Spring已经为杰克逊ObjectMapper提供了bean.因此,我正在尝试自定义此bean,而不是创建一个新bean.

As I understood, Spring is already providing a bean for Jackson ObjectMapper. Therefore, instead of creating a new bean, I'm trying to customize this bean.

博客文章,然后再 Github项目我使用Jackson2ObjectMapperBuilder bean实现了这种自定义.

From this blog post, and then this Github project I used Jackson2ObjectMapperBuilder bean to achieve this customization.

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

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

Then, I was trying to customize the deserializer in order to make it lenient: if an exception is raised when deserializing a property, I want the result object's property to be null and let the deserialization continue (default is to fail on first property that cannot be deserialized).

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

I've been able to achieve that with a class NullableFieldsDeserializationProblemHandler that extends DeserializationProblemHandler (I do not think the code is relevant but if needed, I can share it).

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

The simplest way to register this handler is to use the .addHandler() method of ObjectMapper. But of course, doing like this, I would need to set that every time I inject and use the ObjectMapper. I'd like to be able to configure handler so that every time the ObjectMapper is auto-wired, the handler is already present.

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

The best solution I came up with so far is to use a @PostConstruct annotation only to register the problem handler.

@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(我可以在调试模式下需要它时看到它的发生).

But the problem of this solution is that it seems I can still access an autowired ObjectMapper that doesn't have yet registered the problem handler (I can see it happening after when I need it in debug mode).

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

Any idea how I should register this handler? I've noticed Jackson2ObjectMapperBuilder has a .handlerInstantiator() but I couldn't figure out how to use it.

注意,我还尝试了

Note I've also tried with Jackson2ObjectMapperBuilderCustomizer since I'm using Spring Boot but had no better results.

推荐答案

不可能通过Jackson2ObjectMapperBuilderJackson2ObjectMapperBuilderCustomizerDeserializationProblemHandler直接添加到ObjectMapper. handlerInstanciator()方法用于其他用途.

It's not possible to directly add a DeserializationProblemHandler to the ObjectMapper via a Jackson2ObjectMapperBuilder or Jackson2ObjectMapperBuilderCustomizer. The handlerInstanciator() method is for something else.

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

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

  • 构建器具有modules()方法
  • 该模块可以通过setupModule()访问具有addDeserializationProblemHandler()方法的SetupContext实例
  • the builder has a modules() method
  • the module has access via setupModule() to a SetupContext instance, which has a addDeserializationProblemHandler() method

这有效:

@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());
    } 
}

这篇关于在Spring环境中配置Jackson的DeserializationProblemHandler的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆