jackson全局配置没有生效

jackson全局配置没有生效

描述

springboot项目中,在application.properties中配置了spring.jackson.date-format=yyyy-MM-dd HH:mm:ss,在我的理解中,如果接口接口返回中有Date类型字段,应该默认返回的是如2023-03-13 01:02:03这种格式的,但是实际发现是个long时间戳(或者其他格式的时间)。那么,问题出在哪里了呢。

复现

application.properties
响应结果
controller
响应结果

问题定位

google了一下,发现是@EnableWebMvc影响的。但是为什么会影响到,不太理解。所以得翻翻代码。

@EnableWebMvc这个注解会@Import(DelegatingWebMvcConfiguration.class)DelegatingWebMvcConfiguration继承WebMvcConfigurationSupport。这就导致@EnableAutoConfiguration自动加载类时忽略了WebMvcAutoConfiguration

@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
// 此时已经有了WebMvcConfigurationSupport,所以 WebMvcAutoConfiguration  不会加载了
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
		ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {

正常场景下,WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter#configureMessageConverters(List<HttpMessageConverter<?>> converters) 会引入 converts,但是此时因为没加载,所以没引入。然后走了WebMvcConfigurationSupport#addDefaultHttpMessageConverters(this.messageConverters),这里是加入了默认的converts。默认的不会使用全局配置,所以全局配置没生效。

解决

@Configuration
@Slf4j
public class JacksonConfig implements WebMvcConfigurer {

    @Autowired
    private ObjectMapper objectMapper;

    /**
     * @EnableWebMvc 使用该注解后,需要手动配置  addInterceptors() 和 addResourceHandlers()
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new HandlerInterceptor() {
                    @Override
                    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
                        log.info("JacksonConfig");
                        return HandlerInterceptor.super.preHandle(request, response, handler);
                    }
                }).addPathPatterns("/**")
                .excludePathPatterns("/swagger-ui.html")
                .excludePathPatterns("/null/**")
                .excludePathPatterns("/swagger-resources/**")
                .excludePathPatterns("/swagger/**")
                .excludePathPatterns("/webjars/**")
                .excludePathPatterns("/v2/**");
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
        registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
    }



    /**
     * 填充全局 objectMapper
     * https://stackoverflow.com/questions/45734108/spring-boot-not-using-configured-jackson-objectmapper-with-enablewebmvc
     * @param converters
     */
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.stream().filter(p -> p instanceof MappingJackson2HttpMessageConverter)
                .map(p -> (MappingJackson2HttpMessageConverter)p).forEach(p -> p.setObjectMapper(objectMapper));
        WebMvcConfigurer.super.extendMessageConverters(converters);
    }
}

验证

验证结果

这里格式符合要求了,时区还有点问题。在加个配置就好了spring.jackson.time-zone=GMT+8

结论

@EnableWebMvc 这个注解影响到jackson配置,说实话真没想到。以往看源码也是扫一眼就完事,没仔细看。没考虑到相互之间的影响。目前,其实我对于为啥使用这个注解也表示不太理解,常用的可以通过实现WebMvcRegistrationsWebMvcConfigurer来解决。

参考

stackOverFlow解答

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值