Springboot Jackson配置根本方案, 日期格式化, 时区设置生效

当项目集成配置的功能越来越多, 说不准哪个配置就影响到了什么.

比如你启用了EnableMvC, 默认配置文件配置的一些文件就失效了. 虽然约定大于配置,让springboot可以极简化构建, 但不熟悉内部各个组件执行原理会导致我们经常出一些莫名其妙的问题, 比如配置不生效,比如Jackson的日期格式化.

debug了很久, 配置文件不生效, 直接声明ObjectMapper也不管用. 原因就在于Springboot所谓的简化是通过一系列的条件配置产生, 比如WebMvcConfigurationSupport, 里面到处都是if-else配置逻辑.
这些配置开关复杂且并不知道散落在哪里.

既然如此, 我直接手动配置好了. 关于springboot json序列化的关键是MappingJackson2HttpMessageConverter, 我们需要把springboot默认给配置的converter干掉, 然后放上自己的.

@Configuration
public class RequestHandlerConfig extends WebMvcConfigurationSupport {

    private Logger logger = LoggerFactory.getLogger(RequestHandlerConfig.class);

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //请求上下文初始化拦截器配置
        logger.info("初始化拦截器完成.....");
    }
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html")
            .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
            .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

    @Bean
    public ObjectMapper jacksonObjectMapperCustomization() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        TimeZone timeZone = TimeZone.getTimeZone("Asia/Shanghai");
        format.setTimeZone(timeZone);

        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder()
                .timeZone(timeZone)
                .dateFormat(format);

        return builder.build();
    }
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.removeIf(c -> c instanceof MappingJackson2HttpMessageConverter);
        converters.add(new MappingJackson2HttpMessageConverter(jacksonObjectMapperCustomization()));
    }

}

让LocalDateTime格式化:


import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author Ryan Miao 01399596
 * @date 2021/1/28 16:35
 */
@Configuration
public class DateConfiguration {
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer enumCustomizer() {
        return builder -> builder.deserializerByType(LocalDateTime.class,
            new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
            .deserializerByType(LocalDate.class,
                new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")))
            .serializerByType(LocalDateTime.class,
                new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
            .serializerByType(LocalDate.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")))
            ;
    }

    public static void main(String[] args) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String format = formatter.format(LocalDateTime.now());
        System.out.println(format);
    }

}
posted @ 2020-01-10 14:07  Ryan.Miao  阅读(7410)  评论(0编辑  收藏  举报