最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

spring boot 4.* 自定義序列化器的實現(xiàn)

 更新時間:2026年01月15日 08:33:19   作者:jjscx  
本文介紹了Spring Boot 4.*版本中Jackson自定義序列化器的適配方案,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

一、背景說明

在Spring Boot 4.*版本升級過程中,我們團隊及不少開發(fā)者發(fā)現(xiàn)原有基于Jackson的自定義序列化器/反序列化器全部失效。經(jīng)排查,核心原因是Spring Boot 4.0對Jackson的集成方式做了重大調(diào)整,尤其是自定義序列化組件的注冊機制、基類繼承體系發(fā)生了變化,導(dǎo)致舊版本中基于StdSerializer/StdDeserializer的實現(xiàn)方式不再適用。

為解決這一問題,我們封裝了適配Spring Boot 4.*的Jackson自定義序列化配置類,本文將詳細講解該配置的實現(xiàn)原理、使用方式,并結(jié)合官方文檔說明版本變更的核心點。

二、核心變更(官方文檔參考)

Spring Boot 4.0對JSON處理的Jackson集成做了關(guān)鍵調(diào)整,官方文檔鏈接:https://www.spring-doc.cn/spring-boot/4.0.0/reference_features_json.html

核心變更點:

  1. 序列化/反序列化基類調(diào)整:不再推薦直接繼承StdSerializer/StdDeserializer,而是新增ValueSerializer/ValueDeserializer作為核心基類;
  2. 組件注冊方式優(yōu)化:新增@JacksonComponent注解,替代舊版本的手動注冊方式,實現(xiàn)序列化組件的自動掃描和注冊;
  3. 類型適配性增強:對Java 8時間類型(LocalDate/LocalTime/LocalDateTime)的序列化支持做了重構(gòu),舊版自定義序列化邏輯需適配新基類。

三、適配Spring Boot 4.*的自定義序列化實現(xiàn)

以下是完整的Jackson配置類,實現(xiàn)了Java 8時間類型的自定義序列化/反序列化,適配Spring Boot 4.*版本的核心規(guī)范。

3.1 完整代碼實現(xiàn)

package com.auy.conf;

import org.springframework.boot.jackson.JacksonComponent;
import tools.jackson.core.JacksonException;
import tools.jackson.core.JsonGenerator;
import tools.jackson.core.JsonParser;
import tools.jackson.databind.*;

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

/**
 * Spring Boot 4 兼容的 Jackson 配置
 * 核心適配點:
 * 1. 繼承新版ValueSerializer/ValueDeserializer基類
 * 2. 使用@JacksonComponent注解實現(xiàn)組件自動注冊
 * 3. 適配Java 8時間類型的序列化/反序列化邏輯
 */
@JacksonComponent//:標(biāo)記為Jackson組件,Spring Boot 4會自動掃描并注冊
public class JacksonConfig {

    // 全局時間格式配置(從AuyConfig讀取自定義格式,可根據(jù)業(yè)務(wù)調(diào)整為固定格式)
    public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern(AuyConfig.get().getDateTimeFormat().getDatePattern());
    public static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern(AuyConfig.get().getDateTimeFormat().getTimePattern());
    public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(AuyConfig.get().getDateTimeFormat().getDateTimePattern());

    /**
     * LocalDate 自定義序列化器
     */
    public static class CustomLocalDateSerializer extends ValueSerializer<LocalDate> {
        @Override
        public void serialize(LocalDate v, JsonGenerator g, SerializationContext c) throws JacksonException {
            // 序列化邏輯:LocalDate轉(zhuǎn)指定格式的字符串,null值返回null
            g.writeString(v != null ? DATE_FORMATTER.format(v) : null);
        }
    }

    /**
     * LocalDate 自定義反序列化器
     */
    public static class CustomLocalDateDeserializer extends ValueDeserializer<LocalDate> {
        @Override
        public LocalDate deserialize(JsonParser p, DeserializationContext c) throws JacksonException {
            // 反序列化邏輯:字符串轉(zhuǎn)LocalDate,空值返回null
            String s = p.getValueAsString();
            return s == null || s.isEmpty() ? null : LocalDate.parse(s, DATE_FORMATTER);
        }
    }

    /**
     * LocalTime 自定義序列化器
     */
    public static class CustomLocalTimeSerializer extends ValueSerializer<LocalTime> {
        @Override
        public void serialize(LocalTime v, JsonGenerator g, SerializationContext c) throws JacksonException {
            g.writeString(v != null ? TIME_FORMATTER.format(v) : null);
        }
    }

    /**
     * LocalTime 自定義反序列化器
     */
    public static class CustomLocalTimeDeserializer extends ValueDeserializer<LocalTime> {
        @Override
        public LocalTime deserialize(JsonParser p, DeserializationContext c) throws JacksonException {
            String s = p.getValueAsString();
            return s == null || s.isEmpty() ? null : LocalTime.parse(s, TIME_FORMATTER);
        }
    }

    /**
     * LocalDateTime 自定義序列化器
     */
    public static class CustomLocalDateTimeSerializer extends ValueSerializer<LocalDateTime> {
        @Override
        public void serialize(LocalDateTime v, JsonGenerator g, SerializationContext c) throws JacksonException {
            g.writeString(v != null ? DATE_TIME_FORMATTER.format(v) : null);
        }
    }

    /**
     * LocalDateTime 自定義反序列化器
     */
    public static class CustomLocalDateTimeDeserializer extends ValueDeserializer<LocalDateTime> {
        @Override
        public LocalDateTime deserialize(JsonParser p, DeserializationContext c) throws JacksonException {
            String s = p.getValueAsString();
            return s == null || s.isEmpty() ? null : LocalDateTime.parse(s, DATE_TIME_FORMATTER);
        }
    }
}

3.2 代碼關(guān)鍵說明

  1. 基類適配

    • 序列化器繼承ValueSerializer<T>,反序列化器繼承ValueDeserializer<T>(Spring Boot 4.*推薦的新版基類);
    • 重寫核心方法:序列化器重寫serialize,反序列化器重寫deserialize,方法參數(shù)與舊版兼容,但基類體系不同。
  2. 組件注冊

    • 使用@JacksonComponent注解標(biāo)記基類(會將內(nèi)部類全部注冊)或者內(nèi)部靜態(tài)類(只注冊標(biāo)記的類),Spring Boot 4會自動掃描該注解并將序列化/反序列化器注冊到Jackson容器中,無需手動配置ObjectMapper
    • 該注解替代了舊版本中@Bean注冊SimpleModule的方式,簡化了配置流程。
  3. 時間格式配置

    • AuyConfig讀取自定義的時間格式(日期、時間、日期時間),也可直接替換為固定格式(如yyyy-MM-dd);
    • 處理null值和空字符串:反序列化時對空值做兼容,避免解析異常;序列化時null值返回null,符合JSON規(guī)范。
  4. 包路徑注意

    • Jackson核心類的包路徑為tools.jackson.*(Spring Boot 4.*調(diào)整后的路徑,舊版為com.fasterxml.jackson.*),需確保依賴包版本匹配。

四、使用說明

4.1 依賴要求

確保Spring Boot版本為4.*,且Jackson相關(guān)依賴由Spring Boot父工程管理,無需手動指定版本:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>4.0.0</version>
    <relativePath/>
</parent>

<dependencies>
    <!-- JSON核心依賴(包含Jackson,一般不需要引入,web依賴會自動包含它) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jackson</artifactId>
    </dependency>
</dependencies>

4.2 配置生效條件

  1. JacksonConfig類需放在Spring Boot的掃描路徑下(如com.auy.conf包被@SpringBootApplication掃描);
  2. @JacksonComponent注解會自動觸發(fā)組件注冊,無需額外配置;
  3. AuyConfig需確保能正常獲取時間格式配置,若無需動態(tài)配置,可直接替換為固定格式:
    // 示例:固定格式配置
    public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    public static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss");
    public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    

4.3 驗證方式

編寫測試類,驗證時間類型的序列化/反序列化是否符合預(yù)期:

import com.auy.conf.JacksonConfig;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.time.LocalDateTime;

@SpringBootTest
public class JacksonSerializerTest {

    @Autowired
    private ObjectMapper objectMapper;

    @Test
    public void testLocalDateTimeSerializer() throws Exception {
        LocalDateTime now = LocalDateTime.now();
        // 序列化
        String json = objectMapper.writeValueAsString(now);
        System.out.println("序列化結(jié)果:" + json);
        // 反序列化
        LocalDateTime parsed = objectMapper.readValue(json, LocalDateTime.class);
        System.out.println("反序列化結(jié)果:" + parsed);
    }
}

五、擴展適配其他類型

若需適配其他自定義類型(如枚舉、自定義VO),可參考以下模板:

@JacksonComponent
public static class CustomEnumSerializer extends ValueSerializer<YourEnum> {
    @Override
    public void serialize(YourEnum v, JsonGenerator g, SerializationContext c) throws JacksonException {
        // 自定義枚舉序列化邏輯,如返回枚舉的描述值
        g.writeString(v != null ? v.getDesc() : null);
    }
}

@JacksonComponent
public static class CustomEnumDeserializer extends ValueDeserializer<YourEnum> {
    @Override
    public YourEnum deserialize(JsonParser p, DeserializationContext c) throws JacksonException {
        String s = p.getValueAsString();
        // 自定義枚舉反序列化邏輯
        return s == null ? null : YourEnum.getByDesc(s);
    }
}

六、常見問題解決

  1. 序列化器不生效

    • 檢查@JacksonComponent注解是否添加;
    • 確認JacksonConfig在Spring掃描路徑下;
    • 檢查Jackson包路徑是否為tools.jackson.*(Spring Boot 4.*調(diào)整后的路徑)。
  2. 時間格式解析異常

    • 確認DATE_FORMATTER/TIME_FORMATTER/DATE_TIME_FORMATTER的格式與輸入字符串匹配;
    • 反序列化時增加異常捕獲(可選),適配多格式場景。
  3. 依賴沖突

    • 排除舊版Jackson依賴(com.fasterxml.jackson.*);
    • 確保Spring Boot父工程版本為4.*。

七、總結(jié)

Spring Boot 4.*對Jackson的集成調(diào)整核心在于基類和注冊方式的優(yōu)化,通過繼承ValueSerializer/ValueDeserializer并使用@JacksonComponent注解,可快速適配新版序列化邏輯。本文提供的JacksonConfig類已實現(xiàn)Java 8時間類型的完整適配,可直接復(fù)用或擴展至其他自定義類型,解決升級后序列化器失效的問題。

到此這篇關(guān)于spring boot 4.* 自定義序列化器的實現(xiàn)的文章就介紹到這了,更多相關(guān)springboot 自定義序列化器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 基于@RestControllerAdvice與@ControllerAdvice的區(qū)別說明

    基于@RestControllerAdvice與@ControllerAdvice的區(qū)別說明

    這篇文章主要介紹了@RestControllerAdvice與@ControllerAdvice的區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • 使用Filter攔截器如何實現(xiàn)請求跨域轉(zhuǎn)發(fā)

    使用Filter攔截器如何實現(xiàn)請求跨域轉(zhuǎn)發(fā)

    這篇文章主要介紹了使用Filter攔截器如何實現(xiàn)請求跨域轉(zhuǎn)發(fā),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Springboot如何實現(xiàn)自定義異常數(shù)據(jù)

    Springboot如何實現(xiàn)自定義異常數(shù)據(jù)

    這篇文章主要介紹了Springboot如何實現(xiàn)自定義異常數(shù)據(jù),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-09-09
  • 如何在Springboot實現(xiàn)攔截器功能

    如何在Springboot實現(xiàn)攔截器功能

    其實spring boot攔截器的配置方式和springMVC差不多,只有一些小的改變需要注意下就ok了,下面這篇文章主要給大家介紹了關(guān)于如何在Springboot實現(xiàn)攔截器功能的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • Spring Boot實現(xiàn)Undertow服務(wù)器同時支持HTTP2、HTTPS的方法

    Spring Boot實現(xiàn)Undertow服務(wù)器同時支持HTTP2、HTTPS的方法

    這篇文章考慮如何讓Spring Boot應(yīng)用程序同時支持HTTP和HTTPS兩種協(xié)議。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-12-12
  • Java實現(xiàn)WGS84/百度/騰訊/高德等主流的地理坐標(biāo)轉(zhuǎn)換

    Java實現(xiàn)WGS84/百度/騰訊/高德等主流的地理坐標(biāo)轉(zhuǎn)換

    這篇文章主要為大家詳細介紹了如何使用Java實現(xiàn)WGS84,百度,騰訊,高德等主流的地理坐標(biāo)轉(zhuǎn)換,文中的示例代碼講解詳細,感興趣的小伙伴可以了解下
    2025-12-12
  • Java JDK 動態(tài)代理的使用方法示例

    Java JDK 動態(tài)代理的使用方法示例

    Java 動態(tài)代理機制以巧妙的方式近乎完美地實踐了代理模式的設(shè)計理念。下面這篇文章主要給大家分享了關(guān)于Java JDK 動態(tài)代理的使用方法示例,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-07-07
  • RabbitMQ消息單獨與批量的TTL詳細介紹

    RabbitMQ消息單獨與批量的TTL詳細介紹

    這篇文章主要介紹了RabbitMQ消息單獨與批量的TTL,TTL全名是Time To Live存活時間,表示當(dāng)消息由生產(chǎn)端存入MQ當(dāng)中的存活時間,當(dāng)時間到達的時候還未被消息就會被自動清除,感興趣的同學(xué)可以參考下文
    2023-05-05
  • Java使用EasyExcel實現(xiàn)百萬數(shù)據(jù)導(dǎo)出的最佳實踐指南

    Java使用EasyExcel實現(xiàn)百萬數(shù)據(jù)導(dǎo)出的最佳實踐指南

    這篇文章主要為大家詳細介紹了Java如何使用EasyExcel實現(xiàn)百萬數(shù)據(jù)導(dǎo)出功能,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起了解下
    2026-01-01
  • 詳解Java如何改變字符串中的字符

    詳解Java如何改變字符串中的字符

    這篇文章主要介紹了Java如何改變字符串中的字符,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05

最新評論

靖安县| 浪卡子县| 新沂市| 腾冲县| 内江市| 蒙山县| 樟树市| 岚皋县| 新乡县| 墨江| 象州县| 沈阳市| 云梦县| 涪陵区| 万荣县| 丰县| 桃江县| 中宁县| 周宁县| 开远市| 阳城县| 庆安县| 淮阳县| 宜章县| 江津市| 安岳县| 浦县| 庆云县| 淮滨县| 鹰潭市| 天津市| 博客| 张掖市| 连城县| 卢龙县| 长寿区| 长丰县| 龙胜| 和静县| 监利县| 囊谦县|