在Spring环境中配置Jackson的DeserializationProblemHandler [英] Configure a Jackson's DeserializationProblemHandler in Spring environment
问题描述
据我了解,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.
推荐答案
不可能通过Jackson2ObjectMapperBuilder
或Jackson2ObjectMapperBuilderCustomizer
将DeserializationProblemHandler
直接添加到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 aSetupContext
instance, which has aaddDeserializationProblemHandler()
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屋!