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

一文精通Spring Boot序列化與反序列化(告別數(shù)據(jù)混亂)

 更新時(shí)間:2026年03月17日 09:57:28   作者:加洛斯  
本篇文章主要介紹了序列化與反序列化的概念,以及在SpringBoot中的應(yīng)用,文章通過(guò)通俗易懂的語(yǔ)言和比喻,深入淺出地解釋了這兩個(gè)過(guò)程,并展示了SpringBoot如何通過(guò)SpringMVC和Jackson庫(kù)簡(jiǎn)化數(shù)據(jù)格式轉(zhuǎn)換,感興趣的朋友跟隨小編一起看看吧

大家好,我是加洛斯 ??‍??。作為一名程序員,我深深信奉費(fèi)曼學(xué)習(xí)法——教,是最好的學(xué) ??。這里是我的知識(shí)筆記與分享,旨在把復(fù)雜的東西講明白。如果發(fā)現(xiàn)有誤,萬(wàn)分歡迎你幫我指出來(lái) ??!廢話(huà)不多說(shuō),正文開(kāi)始 ??

在開(kāi)發(fā)中我們經(jīng)常能聽(tīng)到的兩個(gè)詞,序列化與反序列化。很多萌新小白聽(tīng)到這個(gè)概念肯定是滿(mǎn)腦門(mén)問(wèn)號(hào),接下來(lái)我將用通俗易懂的語(yǔ)言和妙趣橫生的比喻,深入淺出的將序列化與反序列的基礎(chǔ)以及原理給大家講述出來(lái)。

一、基礎(chǔ)概念

簡(jiǎn)單來(lái)說(shuō),序列化反序列化 就是 將數(shù)據(jù)在不同格式之間進(jìn)行轉(zhuǎn)換 的過(guò)程,目的是為了在不同的系統(tǒng)或不同的上下文之間傳輸和存儲(chǔ)數(shù)據(jù)

  • 序列化 (Serialization): 將 對(duì)象 轉(zhuǎn)換為 可傳輸或可存儲(chǔ)的格式(通常是 JSON、XML 等)。
    • 在 Spring Boot 中的場(chǎng)景: 當(dāng)你的 Controller 方法返回一個(gè) Java 對(duì)象時(shí),Spring Boot 會(huì)自動(dòng)將它序列化成 JSON 字符串,然后通過(guò) HTTP 響應(yīng)發(fā)送給前端(如瀏覽器、手機(jī) App)。
  • 反序列化 (Deserialization): 將 可傳輸或可存儲(chǔ)的格式(如 JSON、XML)轉(zhuǎn)換回 對(duì)象。
    • 在 Spring Boot 中的場(chǎng)景: 當(dāng)前端通過(guò) HTTP 請(qǐng)求(如 POST、PUT)發(fā)送一個(gè) JSON 數(shù)據(jù)到你的服務(wù)器時(shí),Spring Boot 會(huì)自動(dòng)將這個(gè) JSON 字符串反序列化成你 Controller 方法參數(shù)中定義的 Java 對(duì)象。

那么簡(jiǎn)單來(lái)講就是,序列化是將對(duì)象轉(zhuǎn)化為JSON等格式,反序列化就是將JSON等格式轉(zhuǎn)化為對(duì)象。

二、具體應(yīng)用

Spring Boot 通過(guò)Spring MVC模塊和默認(rèn)集成的Jackson庫(kù),讓這個(gè)過(guò)程變得極為簡(jiǎn)單,但是其背后的原理卻是相當(dāng)復(fù)雜,我們先從簡(jiǎn)單的開(kāi)始來(lái),看看怎么用以及干了什么。

2.1 反序列

假設(shè)前端要?jiǎng)?chuàng)建一個(gè)用戶(hù),它發(fā)送了一個(gè) POST 請(qǐng)求,請(qǐng)求體是 JSON:

{
  "name": "張三",
  "age": 25,
  "email": "zhangsan@example.com"
}

對(duì)應(yīng)的 User 類(lèi)(Java Bean):

// 必須有無(wú)參構(gòu)造函數(shù)
// 必須有為所有屬性生成的 Getter 和 Setter 方法
// lombok注解 自動(dòng)生成getter與setter方法與無(wú)參構(gòu)造函數(shù)
@Data 
public class User {
    private String name;
    private Integer age;
    private String email;
}

在你的 Spring Boot Controller 中,你會(huì)這樣寫(xiě):

@RestController
public class UserController {
    @PostMapping("/users")
    public ResponseEntity<String> createUser(@RequestBody User user) { 
        // 在這個(gè)方法內(nèi)部,User 對(duì)象已經(jīng)是一個(gè)可以直接使用的 Java 對(duì)象了
        System.out.println("用戶(hù)名:" + user.getName());
        System.out.println("年齡:" + user.getage());
        // ... 保存用戶(hù)到數(shù)據(jù)庫(kù)等操作
        return ResponseEntity.ok("用戶(hù)創(chuàng)建成功");
    }
}

這里發(fā)生了什么?

  1. 前端發(fā)送 JSON 數(shù)據(jù)。
  2. Spring Boot 看到 @RequestBody 注解和 User 這個(gè)參數(shù)類(lèi)型。
  3. Spring Boot 使用 Jackson 庫(kù) 反序列化 JSON 字符串,根據(jù) JSON 的 key 匹配 User 類(lèi)的屬性(如 name 匹配 name),并創(chuàng)建一個(gè) User 對(duì)象。
  4. 這個(gè)創(chuàng)建好的 User 對(duì)象被傳入你的 createUser 方法中。

這樣我們就從前端發(fā)送的JSON中解析了我們需要的數(shù)據(jù),是不是很簡(jiǎn)單,現(xiàn)在沒(méi)有配置任何文件,緊靠SpringBoot自帶的Jackson庫(kù)就完成了反序列化。

2.2 序列化

同樣一個(gè) Controller,我們寫(xiě)一個(gè)查詢(xún)用戶(hù)的方法:

@RestController
public class UserController {
    @GetMapping("/users/{id}")
    public User getUser(@PathVariable Long id) {
        // 假設(shè)從數(shù)據(jù)庫(kù)或其他地方查詢(xún)到了一個(gè)用戶(hù)
        User user = new User();
        user.setName("李四");
        user.setAge(30);
        user.setEmail("lisi@example.com");
        // 直接返回這個(gè)對(duì)象
        return user;
    }
}

這里發(fā)生了什么?

  1. 你的方法返回了一個(gè) User 對(duì)象。
  2. Spring Boot 看到返回值后,使用 Jackson 庫(kù) 序列化 這個(gè) User 對(duì)象。
  3. 最終,前端收到的 HTTP 響應(yīng)體就是這樣的 JSON 字符串:
{
  "name": "李四",
  "age": 30,
  "email": "lisi@example.com"
}

三、Jackson

SpringBoot通過(guò)自動(dòng)配置和默認(rèn)的 Jackson 集成,極大地簡(jiǎn)化了 Web 開(kāi)發(fā)中數(shù)據(jù)格式轉(zhuǎn)換的復(fù)雜性。開(kāi)發(fā)者幾乎不需要編寫(xiě)轉(zhuǎn)換代碼,只需關(guān)注業(yè)務(wù)邏輯(定義對(duì)象、編寫(xiě) Controller),就能輕松實(shí)現(xiàn) RESTful API 的數(shù)據(jù)交互。我們來(lái)學(xué)習(xí)幾個(gè)常用的 Jackson 注解。

  • @JsonIgnore:在序列化時(shí)忽略某個(gè)屬性。
public class User {
    private String name;
    @JsonIgnore // 返回給前端的 JSON 中不會(huì)包含 password 字段,保障安全
    private String password;
}
  • @JsonProperty:為屬性指定一個(gè)別名。
public class User {
    @JsonProperty("full_name") // 序列化后 JSON 中的 key 是 "full_name"
    private String name;
}
  • @JsonFormat:格式化日期字段。
public class User {
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;
}
  • @JsonInclude:控制序列化時(shí)包含哪些屬性。
@JsonInclude(JsonInclude.Include.NON_NULL) // 只包含非 null 字段
public class User {
    private String name;
    private Integer age; // 如果 age 為 null,則序列化結(jié)果中無(wú)此字段
}
  • @JsonView:定義視圖,實(shí)現(xiàn)不同接口返回不同字段。
public class Views {
    public static class Public {} // 公共視圖
    public static class Internal extends Public {} // 內(nèi)部視圖,繼承公共視圖
}
public class User {
    @JsonView(Views.Public.class)
    private String name;
    @JsonView(Views.Internal.class)
    private String email;
}
@RestController
public class UserController {
    @GetMapping("/user/public")
    @JsonView(Views.Public.class) // 只序列化 Public 視圖的字段
    public User getPublicUser() { ... }
    @GetMapping("/user/internal")
    @JsonView(Views.Internal.class) // 序列化 Internal 和 Public 視圖的字段
    public User getInternalUser() { ... }
}
過(guò)程方向動(dòng)作比喻Spring Boot 中的關(guān)鍵注解
序列化對(duì)象 -> JSON將Java對(duì)象轉(zhuǎn)換為傳輸/存儲(chǔ)格式打包(默認(rèn)行為,無(wú)需注解)
反序列化JSON -> 對(duì)象將傳輸/存儲(chǔ)格式轉(zhuǎn)換為Java對(duì)象拆包組裝@RequestBody

四、原理

Spring Boot 的序列化與反序列化其背后是一套名為 HttpMessageConverter 的可插拔策略接口。

  • 工作原理:  當(dāng) Spring MVC 處理一個(gè) HTTP 請(qǐng)求時(shí),它會(huì)根據(jù)請(qǐng)求的 Content-Type(反序列化)和 Accept(序列化)頭,以及目標(biāo)方法的參數(shù)/返回類(lèi)型,來(lái)選擇一個(gè)合適的 HttpMessageConverter 實(shí)現(xiàn)。
  • 可插拔性:  你可以自定義或替換這些轉(zhuǎn)換器,從而支持不同的數(shù)據(jù)格式(如 JSON、XML、Protobuf 等)。

Spring Boot 通過(guò)自動(dòng)配置,默認(rèn)為我們注冊(cè)了以下常用的轉(zhuǎn)換器:

轉(zhuǎn)換器類(lèi)支持格式說(shuō)明
MappingJackson2HttpMessageConverterJSON默認(rèn),使用 Jackson 庫(kù)
GsonHttpMessageConverterJSON使用 Google 的 Gson 庫(kù)
Jaxb2RootElementHttpMessageConverterXML處理 XML 格式

如何切換?  例如,如果你想用 Gson 替代 Jackson,只需在 pom.xml 中排除 Jackson 并引入 Gson 依賴(lài),Spring Boot 會(huì)自動(dòng)切換默認(rèn)的 JSON 轉(zhuǎn)換器。

五、自定義序列化與反序列化器

當(dāng)默認(rèn)行為無(wú)法滿(mǎn)足復(fù)雜需求時(shí),可以編寫(xiě)自定義的 JsonSerializer 和 JsonDeserializer。 我們希望將 Money 對(duì)象序列化為 "100.00元" 的格式。

// 1. 自定義序列化器
public class MoneySerializer extends JsonSerializer<Money> {
    @Override
    public void serialize(Money value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        // 將 Money 對(duì)象轉(zhuǎn)換為字符串
        String moneyStr = value.getAmount() + "元";
        gen.writeString(moneyStr);
    }
}
// 2. 自定義反序列化器
public class MoneyDeserializer extends JsonDeserializer<Money> {
    @Override
    public Money deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        String text = p.getText(); // 例如 "100.00元"
        // 解析字符串,創(chuàng)建 Money 對(duì)象
        String amountStr = text.replace("元", "");
        BigDecimal amount = new BigDecimal(amountStr);
        return new Money(amount);
    }
}
// 3. 在 Money 類(lèi)上使用注解綁定
public class Money {
    private BigDecimal amount;
    @JsonSerialize(using = MoneySerializer.class)
    @JsonDeserialize(using = MoneyDeserializer.class)
    public BigDecimal getAmount() {
        return amount;
    }
}

在 application.properties 或通過(guò)配置類(lèi) Jackson2ObjectMapperBuilderCustomizer 可以進(jìn)行全局配置,避免在每個(gè)類(lèi)上重復(fù)注解。

配置文件方式:

# 縮進(jìn)輸出,便于閱讀
spring.jackson.serialization.indent-output=true
# 忽略未知屬性,反序列化時(shí)如果JSON有類(lèi)中沒(méi)有的字段不報(bào)錯(cuò)
spring.jackson.deserialization.fail-on-unknown-properties=false
# 日期全局格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
# 忽略值為 null 的字段
spring.jackson.default-property-inclusion=non_null

配置類(lèi)方式(Configuration):

@Configuration
public class JacksonConfig {
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jacksonCustomizer() {
        return builder -> {
            builder.serializationInclusion(JsonInclude.Include.NON_NULL);
            builder.featuresToEnable(SerializationFeature.INDENT_OUTPUT);
            builder.featuresToDisable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
            builder.simpleDateFormat("yyyy-MM-dd HH:mm:ss");
        };
    }
}

到此這篇關(guān)于一文精通Spring Boot序列化與反序列化(告別數(shù)據(jù)混亂)的文章就介紹到這了,更多相關(guān)Spring Boot序列化與反序列化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中二叉樹(shù)的建立和各種遍歷實(shí)例代碼

    Java中二叉樹(shù)的建立和各種遍歷實(shí)例代碼

    這篇文章主要介紹了Java中二叉樹(shù)的建立和各種遍歷實(shí)例代碼,涉及樹(shù)節(jié)點(diǎn)的定義,后序遍歷,層序遍歷,深度優(yōu)先和廣度優(yōu)先等相關(guān)內(nèi)容,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-01-01
  • Java初始化塊及執(zhí)行過(guò)程解析

    Java初始化塊及執(zhí)行過(guò)程解析

    這篇文章主要介紹了Java初始化塊及執(zhí)行過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • Java源碼解析CopyOnWriteArrayList的講解

    Java源碼解析CopyOnWriteArrayList的講解

    今天小編就為大家分享一篇關(guān)于Java源碼解析CopyOnWriteArrayList的講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-01-01
  • springboot如何開(kāi)啟一個(gè)監(jiān)聽(tīng)線程執(zhí)行任務(wù)

    springboot如何開(kāi)啟一個(gè)監(jiān)聽(tīng)線程執(zhí)行任務(wù)

    這篇文章主要介紹了springboot如何開(kāi)啟一個(gè)監(jiān)聽(tīng)線程執(zhí)行任務(wù)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • 用Maven插件生成Mybatis代碼的實(shí)現(xiàn)方法

    用Maven插件生成Mybatis代碼的實(shí)現(xiàn)方法

    本文主要介紹 Maven插件生成Mybatis代碼,現(xiàn)在做開(kāi)發(fā)的朋友有好多用Maven 來(lái)管理代碼,這里給大家舉個(gè)例子,有需要的同學(xué)可以看下
    2016-07-07
  • SpringBoot2.0新特性之配置綁定全解析

    SpringBoot2.0新特性之配置綁定全解析

    在Spring Boot 2.0中推出了Relaxed Binding 2.0,對(duì)原有的屬性綁定功能做了非常多的改進(jìn)以幫助我們更容易的在Spring應(yīng)用中加載和讀取配置信息,感興趣的小伙伴們可以參考一下
    2019-03-03
  • 實(shí)例分析Java泛型

    實(shí)例分析Java泛型

    本篇文章通過(guò)代碼實(shí)例給大家講述了Java泛型的相關(guān)知識(shí)點(diǎn)以及相關(guān)的代碼分析,對(duì)此有興趣的朋友學(xué)習(xí)下。
    2018-02-02
  • Java詳細(xì)講解依賴(lài)注入的方式

    Java詳細(xì)講解依賴(lài)注入的方式

    Idea中使用@Autowire注解會(huì)出現(xiàn)提示黃線,強(qiáng)迫癥患者看著很難受,使用構(gòu)造器注入或者setter方法注入后可解決,下面我們一起來(lái)看看
    2022-06-06
  • Servlet注解之@WebInitParam多個(gè)InitParam的使用

    Servlet注解之@WebInitParam多個(gè)InitParam的使用

    這篇文章主要介紹了Servlet注解之@WebInitParam多個(gè)InitParam的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • 使用Java提取PDF中的文字的三種常見(jiàn)方法

    使用Java提取PDF中的文字的三種常見(jiàn)方法

    這篇文章主要介紹了Java中提取PDF文本的三種方法:ApachePDFBox(普通PDF,輕量易用)、iText(復(fù)雜格式,功能強(qiáng)大)、TesseractOCR(掃描版,需OCR識(shí)別),并給出各場(chǎng)景下的推薦選擇,需要的朋友可以參考下
    2025-06-06

最新評(píng)論

石泉县| 武宁县| 阳新县| 博兴县| 凉山| 庆安县| 湘潭市| 阿拉善左旗| 浠水县| 永善县| 顺平县| 綦江县| 梓潼县| 澄江县| 萨嘎县| 无为县| 连州市| 阿坝县| 姚安县| 长岭县| 广灵县| 嘉黎县| 全南县| 定陶县| 荃湾区| 礼泉县| 安达市| 东乡| 彰武县| 多伦县| 横山县| 高台县| 喜德县| 英吉沙县| 永平县| 周至县| 桦川县| 东台市| 通山县| 连平县| 清镇市|