MappingJackson2HttpMessageConverter在Spring 4启动时多次实例化覆盖(null)自定义ObjectMapper设置

时间:2018-05-15 14:15:51

标签: java spring spring-mvc objectmapper

我正在尝试将我的ObjectMapper配置为具有特定的TimeZone而不是使用默认GMT。我按照不同地方的说明(参见下面的参考资料)尝试通过代码和XML进行配置。在调试之后我注意到代码确实设置了ObjectMapper的TimeZone设置一次,但是在启动期间多次调用Jackson2ObjectMapperBuilder类并覆盖(null)我的TimeZone设置并在启动过程完成时返回到默认GMT,两者都是在Tomcat和我的单元测试中。

一些代码:

配置:

@Configuration
@EnableWebMvc
public class JacksonMapperConfiguration extends WebMvcConfigurerAdapter {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(converter());
    }

    @Bean    
    public MappingJackson2HttpMessageConverter converter() {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(jacksonObjectMapper());
        return converter;
    }

    @Bean
    public ObjectMapper jacksonObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setTimeZone(TimeZone.getTimeZone("America/New_York"));
        return objectMapper;
    }

    @Bean
    public Jackson2ObjectMapperBuilder jacksonBuilder() {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.timeZone("America/New_York");
        return builder;
    }
}

实体:

@Entity
public class AllocationEstimate extends AbstractEntity<Integer> {

    private static final long serialVersionUID = 1L;

    @NotNull(message = "validation.mandatoryField")
    @Column(nullable = false)
    @Temporal(TemporalType.DATE)
    @JsonFormat(pattern = "MM/dd/yyyy")
    private Date endDate;

    public Date getEndDate() {
        return endDate;
    }

    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }
}

控制器:

@RestController
@RequestMapping("/allocation-estimate")
public class AllocationEstimateRestController extends AbstractGenericCrudRestController<AllocationEstimate, Integer> {

    private final AllocationEstimateService allocationEstimateService;

    @Autowired
    public AllocationEstimateRestController(AllocationEstimateService allocationEstimateService) {
        this.AllocationEstimateService = allocationEstimateService;
    }

    @Override
    @Post
    public AllocationEstimate createOrUpdate(@RequestBody @Valid AllocationEstimate resource) {
        return super.createOrUpdate(resource);
    }
}

我已经使用了上述所有内容以及不同设置的组合。有些只有configureMessageConverters,或者只是尝试设置@Bean。

我的问题是,是否有人看过这种行为,我该如何解决?我尝试了不同的组合,但我的设置总是在启动过程结束时被覆盖。我使用的是Spring 4.3.16。

供参考:

Configuring ObjectMapper in Spring

https://dzone.com/articles/latest-jackson-integration

https://www.javacodegeeks.com/2014/09/customizing-httpmessageconverters-with-spring-boot-and-spring-mvc.html

How to force Jackson2ObjectMapperBuilder in spring-boot?

SpringMVC Jackson2HttpMessageConverter customization doesn't work

修改 我怀疑AllEncompassingFormHttpMessageConverter是罪魁祸首,我不确定它是什么,但有些东西多次实例化这个类,这反过来多次实例化MappingJackson2HttpMessageConverter,从而覆盖了我在配置中的转换器。

2 个答案:

答案 0 :(得分:1)

@Primary添加到您的jacksonObjectMapper()jacksonBuilder() bean。

我认为Spring尝试初始化一些隐藏的ObjectMapper被不同的罐子拉入,主要的不是你的。

答案 1 :(得分:0)

我通过在Spring Boot实例化ObjectMapper bean目录之后解决了这个问题。

    @Configuration
    @AutoConfigureAfter(JacksonAutoConfiguration.class)
    public static class RegistryJsonConfigurer implements InitializingBean {

        @Autowired
        private ObjectMapper objectMapper;

        @Override
        public void afterPropertiesSet() {
            SimpleModule module = new SimpleModule();
            module.addDeserializer(Something.class, new CustomDeserializer<>(Something.class));
            objectMapper.registerModule(module);
        }
    }