SpringBoot中自定義Jackson行為


Spring Boot如何自動裝配Jackson

Jackson的自動配置類為JacksonAutoConfiguration,由spring-boot-autoconfigure-*.jar中的META-INF/spring.factories文件中指定,如下所示:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
...
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
...

自動配置過程如下:

@Configuration
@ConditionalOnClass(Jackson2ObjectMapperBuilder.class)
static class JacksonObjectMapperConfiguration {

    /**
     * 注冊ObjectMapper對象,其中通過Jackson2ObjectMapperBuilder類構建ObjectMapper
     */
    @Bean
    @Primary
    @ConditionalOnMissingBean
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
        return builder.createXmlMapper(false).build();
    }

}

@Configuration
@ConditionalOnClass(Jackson2ObjectMapperBuilder.class)
static class JacksonObjectMapperBuilderConfiguration {

    private final ApplicationContext applicationContext;

    JacksonObjectMapperBuilderConfiguration(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    /**
     * 創建Jackson2ObjectMapperBuilder對象,從上一步可知,創建ObjectMapper時需要該對象。
     * 其中可以通過Jackson2ObjectMapperBuilderCustomizer來定義Jackson2ObjectMapperBuilder。
     * 因此自定義Jackson行為的方式就呼之欲出了,只要在應用中注冊一個我們的
     * Jackson2ObjectMapperBuilderCustomizer對象到容器中即可。
     */
    @Bean
    @ConditionalOnMissingBean
    public Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder(
        List<Jackson2ObjectMapperBuilderCustomizer> customizers) {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.applicationContext(this.applicationContext);
        customize(builder, customizers);
        return builder;
    }
}

自定義Jackson行為

如以下代碼所示

package com.wangtao.springboottest.config;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

@Component
public class JacksonCustomizer implements Jackson2ObjectMapperBuilderCustomizer {

    private static final String STANDARD_PATTERN = "yyyy-MM-dd HH:mm:ss";

    private static final String DATE_PATTERN = "yyyy-MM-dd";

    private static final String TIME_PATTERN = "HH:mm:ss";

    @Override
    public void customize(Jackson2ObjectMapperBuilder builder) {
        // 初始化JavaTimeModule
        JavaTimeModule javaTimeModule = new JavaTimeModule();

        //處理LocalDateTime
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter
            .ofPattern(STANDARD_PATTERN);
        javaTimeModule.addSerializer(LocalDateTime.class, 
                                     new LocalDateTimeSerializer(dateTimeFormatter));
        javaTimeModule.addDeserializer(LocalDateTime.class, 
                                       new LocalDateTimeDeserializer(dateTimeFormatter));

        //處理LocalDate
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(DATE_PATTERN);
        javaTimeModule.addSerializer(LocalDate.class, 
                                     new LocalDateSerializer(dateFormatter));
        javaTimeModule.addDeserializer(LocalDate.class, 
                                       new LocalDateDeserializer(dateFormatter));

        //處理LocalTime
        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern(TIME_PATTERN);
        javaTimeModule.addSerializer(LocalTime.class, 
                                     new LocalTimeSerializer(timeFormatter));
        javaTimeModule.addDeserializer(LocalTime.class, 
                                       new LocalTimeDeserializer(timeFormatter));

        /*
         * 1. java.util.Date yyyy-MM-dd HH:mm:ss
         * 2. 支持JDK8 LocalDateTime、LocalDate、 LocalTime
         * 3. Jdk8Module模塊支持如Stream、Optional等類
         * 4. 序列化時包含所有字段
         * 5. 在序列化一個空對象時時不拋出異常
         * 6. 忽略反序列化時在json字符串中存在, 但在java對象中不存在的屬性
         * 7. 數字序列化成字符穿且調用BigDecimal.toPlainString()方法
         */
        builder.simpleDateFormat(STANDARD_PATTERN)
                .modules(javaTimeModule, new Jdk8Module())
                .serializationInclusion(JsonInclude.Include.ALWAYS)
                .failOnEmptyBeans(false)
                .failOnUnknownProperties(false)
                .featuresToEnable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN)
                .featuresToEnable(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS);
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM