springboot2 elegant personalized custom Jackson configuration

foreword

By implementing the Jackson2ObjectMapperBuilderCustomizer interface and registering it in the container for personalized customization, Spring Boot will not overwrite the default ObjectMapper configuration, but merge and enhance it. Specifically, it will also be sorted according to the Order priority of the Jackson2ObjectMapperBuilderCustomizer implementation class, so the above JacksonConfig configuration The class also implements the Ordered interface.

The default Jackson2ObjectMapperBuilderCustomizerConfiguration priority is 0, so if we want to override the configuration, set the priority to be greater than 0.

**Note: **In the SpringBoot2 environment, do not inject the custom ObjectMapper object into the container, as this will overwrite the original ObjectMapper configuration!

An example of elegant and personalized Jackson implementation

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
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.moyu.common.Constants;
import org.moyu.common.serializer.JacksonLocalDateTimeDeserializer;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import java.io.IOException;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

/**
 * 自定义Jackson配置
 */
@Configuration
public class JacksonConfig implements Jackson2ObjectMapperBuilderCustomizer, Ordered {
    
    
    @Override
    public void customize(Jackson2ObjectMapperBuilder builder) {
    
    
        // 将入参中的空字符串""转为null
        builder.deserializerByType(String.class, new StdScalarDeserializer<String>(String.class) {
    
    
            @Override
            public String deserialize(JsonParser jsonParser, DeserializationContext ctx)
                    throws IOException {
    
    
                // 重点在这儿:如果为空白则返回null
                String value = jsonParser.getValueAsString();
                if (value == null || "".equals(value.trim())) {
    
    
                    return null;
                }
                return value;
            }
        });

        // 设置java.util.Date时间类的序列化以及反序列化的格式
        builder.simpleDateFormat(Constants.YYYY_MM_DD_HH_MM_SS);

        // JSR 310日期时间处理
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(Constants.YYYY_MM_DD_HH_MM_SS)));
        javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(Constants.YYYY_MM_DD)));
        javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(Constants.HH_MM_SS)));
        javaTimeModule.addDeserializer(LocalDateTime.class, new JacksonLocalDateTimeDeserializer());
        javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(Constants.YYYY_MM_DD)));
        javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(Constants.HH_MM_SS)));
        builder.modules(javaTimeModule);

        // 全局转化Long类型为String,解决序列化后传入前端Long类型精度丢失问题
        builder.serializerByType(BigInteger.class, ToStringSerializer.instance);
        builder.serializerByType(Long.class, ToStringSerializer.instance);
    }

    @Override
    public int getOrder() {
    
    
        return 1;
    }
}

JacksonLocalDateTimeDeserializer

public class JacksonLocalDateTimeDeserializer extends StdDeserializer<LocalDateTime> {
    
    
    public JacksonLocalDateTimeDeserializer() {
    
    
        super(LocalDateTime.class);
    }

    protected JacksonLocalDateTimeDeserializer(Class<?> vc) {
    
    
        super(vc);
    }

    public LocalDateTime deserialize(JsonParser jp, DeserializationContext deserializationContext) throws IOException {
    
    
        String dateText = jp.getValueAsString();
        DateTime parse = DateUtil.parse(dateText);
        Instant instant = parse.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        return instant.atZone(zoneId).toLocalDateTime();
    }
}

Guess you like

Origin blog.csdn.net/q283614346/article/details/131884290