3

据我了解,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(),但我不知道如何使用它。

注意我也尝试过Jackson2ObjectMapperBuilderCustomizer,因为我使用的是 Spring Boot,但没有更好的结果。

4

2 回答 2

3

无法直接将 a 添加DeserializationProblemHandlerObjectMappervia aJackson2ObjectMapperBuilderJackson2ObjectMapperBuilderCustomizer。该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());
    } 
}
于 2018-02-26T09:00:37.360 回答
1

像这样写一个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;
    }
}

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

@JsonIgnoreProperties(ignoreUnknown = true)
于 2018-02-13T19:03:28.933 回答