配置SpringBoot中的Jackson序列化方式
在開發(fā)基于Spring Boot的應(yīng)用程序時,Jackson是默認的JSON序列化和反序列化工具。
它提供了強大的功能,可以靈活地處理JSON數(shù)據(jù)。然而,Jackson的默認行為可能無法完全滿足我們的需求。
例如,日期格式、空值處理、數(shù)據(jù)精度等問題可能需要自定義配置。本文將詳細介紹如何在Spring Boot中配置Jackson,以滿足這些需求。
1. 為什么需要自定義Jackson配置?
Jackson的默認行為在大多數(shù)情況下是合理的,但在實際開發(fā)中,我們可能需要對以下方面進行自定義:
- 日期格式:默認情況下,Jackson會將日期序列化為時間戳,這可能不符合我們的需求。
- 空值處理:默認情況下,Jackson會忽略空值,但我們可能需要保留空值。
- 數(shù)據(jù)精度:對于
BigDecimal和BigInteger等類型,直接序列化可能會導(dǎo)致精度問題。 - 自定義序列化:對于某些復(fù)雜類型,我們可能需要自定義序列化邏輯。
2. 配置JacksonConfig
在Spring Boot中,可以通過創(chuàng)建一個@Configuration類并定義一個ObjectMapper的Bean來自定義Jackson的行為。
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
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.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 com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.TimeZone;
/**
* @author XiaoXin
*/
@Configuration
public class JacksonConfig {
@Bean
@Primary
@ConditionalOnMissingBean(ObjectMapper.class)
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
builder.simpleDateFormat("yyyy-MM-dd HH:mm:ss");
ObjectMapper objectMapper = builder.createXmlMapper(false)
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.featuresToDisable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE)
.timeZone(TimeZone.getTimeZone("Asia/Shanghai"))
.build();
// null數(shù)據(jù)返回
objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 反序列化時候遇到不匹配的屬性并不拋出異常
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// 序列化時候遇到空對象不拋出異常
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
// 反序列化的時候如果是無效子類型,不拋出異常
objectMapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false);
// 不使用默認的dateTime進行序列化,
objectMapper.configure(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS, false);
// 數(shù)據(jù)精度問題
SimpleModule simpleModule = new SimpleModule()
.addSerializer(Long.class, ToStringSerializer.instance)
.addSerializer(Long.TYPE, ToStringSerializer.instance)
.addSerializer(BigInteger.class, ToStringSerializer.instance)
.addSerializer(BigDecimal.class, ToStringSerializer.instance);
objectMapper.registerModule(simpleModule);
// 配置Java 8時間日期模塊
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
objectMapper.registerModule(javaTimeModule).registerModule(new ParameterNamesModule());
return objectMapper;
}
}
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
關(guān)于SpringBoot自定義條件注解與自動配置
這篇文章主要介紹了關(guān)于SpringBoot自定義條件注解與自動配置,Spring Boot的核心功能就是為整合第三方框架提供自動配置,而本文則帶著大家實現(xiàn)了自己的自動配置和Starter,需要的朋友可以參考下2023-07-07
淺談Java內(nèi)存區(qū)域與對象創(chuàng)建過程
下面小編就為大家?guī)硪黄獪\談Java內(nèi)存區(qū)域與對象創(chuàng)建過程。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-07-07
Spring利用@Validated注解實現(xiàn)參數(shù)校驗詳解
這篇文章主要為大家詳細介紹了在?Spring?項目中使用?@Validated?進行參數(shù)校驗的方法和常見應(yīng)用場景,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-05-05
Java并發(fā)編程如何降低鎖粒度并實現(xiàn)性能優(yōu)化
這篇文章主要介紹了Java并發(fā)編程如何降低鎖粒度并實現(xiàn)性能優(yōu)化,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-08-08

