@JsonView + 單一 DTO:如何實現多場景 JSON 字段動態渲染

@JsonView + 單一 DTO:如何實現多場景 JSON 字段動態渲染

  • @JsonView + 單一 DTO:如何實現多場景 JSON 字段動態渲染
    • 1、@JsonView 注解產生的背景
    • 2、為了滿足不同場景下返回對應的屬性的做法有哪些?
      • 2.1 最快速的實現則是針對不同場景新建不同的 DTO 對象
      • 2.2 使用 @JsonView 注解實現不同DTO對象的返回
        • 2.2.1 定義同一個 DTO 對象
        • 2.2.2 區分不同的響應視圖
        • 2.2.3 Controller 層的調用
        • 2.2.4 簡要信息 視圖 DTO
        • 2.2.5 詳情信息 視圖 DTO
      • 2.3 問題已解決(引入原理實現篇)
    • 3、Debug調試篇
      • 3.1 SpringMvc 切入點 對應的核心代碼片段
      • 3.2 字段屬性序列化核心邏輯
      • 3.3 多種 DTO 視圖 Demo 驗證
        • 3.3.1 ObjectMapper 配置視圖 View
        • 3.3.2 ObjectWriter 配置視圖 View
      • 3.4 小結
    • 4、擴展點
      • 4.1 ResponseBodyAdvice接口
      • 4.2 RequestBodyAdvice接口

@JsonView + 單一 DTO:如何實現多場景 JSON 字段動態渲染

1、@JsonView 注解產生的背景

@JsonView 是 Jackson 庫提供的一個注解,用于控制 Java 對象序列化為 JSON 時的字段可見性。通過定義不同的“視圖”(View),可以靈活地決定哪些字段在特定場景下被序列化,從而避免為不同接口編寫多個相似的 DTO 類。

2、為了滿足不同場景下返回對應的屬性的做法有哪些?

2.1 最快速的實現則是針對不同場景新建不同的 DTO 對象

在這里插入圖片描述

細心的童鞋可以發現:雖然是不同的 DTO,但是存在共同的屬性,而且比如后面再來一個需求,這個接口僅返回基本信息的字段(外加一個手機號字段),那么我們是不是還需要創建一個新的 DTO 對象呢?如果針對每一個接口返回都定義一個 DTO 對象的話,對于后端代碼的維護也是相當的冗余操作,鑒于這種需求,有沒有一種對應后端的 其他 解決方案呢?答案是有的。即就是(@JsonView注解)。

2.2 使用 @JsonView 注解實現不同DTO對象的返回

2.2.1 定義同一個 DTO 對象
/*** @Description 用戶DTO* @Author Mr.Gao* @Date 2025/4/16 23:43*/
@Getter
@Setter
public class User {/*** 用戶姓名*/@JsonView(SimpleInfoView.class)private String username;/*** 用戶年齡*/@JsonView(SimpleInfoView.class)private Integer age;/*** 用戶性別*/@JsonView(SimpleInfoView.class)private String sex;/*** =================以下信息為用戶敏感信息不能給用戶返回================*//*** 手機號碼*/@JsonView(SensitiveInfoView.class)private String mobileNo;/*** 登錄密碼*/@JsonView(SensitiveInfoView.class)private String loginPwd;/*** 支付密碼*/@JsonView(SensitiveInfoView.class)private String payPwd;
}
2.2.2 區分不同的響應視圖
/*** @Description 簡單視圖展示View信息* @Author Mr.Gao*/
public interface SimpleInfoView {
}------ 視圖與視圖之間是可以繼承的,那么也就實現既包含基礎信息字段又包含需要的字段,進而實現不同DTO的返回 ---
/*** @Description 敏感信息* @Author Mr.Gao*/
public interface SensitiveInfoView extends SimpleInfoView {
}
2.2.3 Controller 層的調用
/*** @Description 用戶控制層* @Author Mr.Gao* @Date 2025/4/16 23:50*/
@RestController
public class UserController {/*** 模擬從數據庫獲取用戶信息** @return*/public static User getUserInfoFromDB() {User user = new User();user.setUsername("Mr.Gao");user.setAge(18);user.setSex("男");user.setMobileNo("12345678901");user.setLoginPwd("123456");user.setPayPwd("123456");return user;}/*** 獲取用戶簡要信息** @return*/@JsonView(SimpleInfoView.class) // 返回簡要信息的視圖DTO@GetMapping("/user/getUserSimpleInfo")public User getUserSimpleInfo() {return getUserInfoFromDB();}/*** 獲取用戶詳細信息** @return*/@JsonView(SensitiveInfoView.class)// 返回詳情信息的視圖DTO@GetMapping("/user/getUserDetailInfo")public User getUserDetailInfo() {return getUserInfoFromDB();}}
2.2.4 簡要信息 視圖 DTO

在這里插入圖片描述

2.2.5 詳情信息 視圖 DTO

在這里插入圖片描述

2.3 問題已解決(引入原理實現篇)

經過上述代碼案例操作,確實是可以解決我們后端程序猿的新建多個 DTO 對象的冗余問題,童鞋們可以都試試,但是出于好奇,為了什么在 一個實體對象 DTO 和 controller 層的方法 增加 @JsonView 注解之后就能實現不同視圖的效果呢?其中究竟是使用了什么魔法呢?接下來我們繼續進入 Debug 調試篇,繼續 gank 它。

3、Debug調試篇

3.1 SpringMvc 切入點 對應的核心代碼片段

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

3.2 字段屬性序列化核心邏輯

在這里插入圖片描述
在這里插入圖片描述

經過上述分析可得,設置視圖的核心代碼為 objectMapper.writerWithView(serializationView) ,然后調用 objectMapper.writeValueAsString 方法是否可以實現不同視圖的 DTO 輸出呢?

3.3 多種 DTO 視圖 Demo 驗證

3.3.1 ObjectMapper 配置視圖 View
@Test
public void testJsonViewAnnotationConvertMutiDTOByObjectMapper() throws JsonProcessingException {User user = UserController.getUserInfoFromDB();// @1: 設置序列化視圖為SimpleInfoView(輸出簡要信息)objectMapper.setConfig(objectMapper.getSerializationConfig().withView(SimpleInfoView.class));// @2: 設置序列化視圖為SensitiveInfoView(輸出詳細信息)//objectMapper.setConfig(objectMapper.getSerializationConfig()//        .withView(SensitiveInfoView.class));System.out.println("采用Object序列化視圖:" + objectMapper.getSerializationConfig().getActiveView());String JsonResult = objectMapper.writeValueAsString(user);System.out.println(JsonResult);
}
3.3.2 ObjectWriter 配置視圖 View
@Test
public void testJsonViewAnnotationConvertMutiDTOByObjectWriter() throws JsonProcessingException {User user = UserController.getUserInfoFromDB();// @1: 設置序列化視圖為SimpleInfoView(輸出簡要信息)//ObjectWriter objectWriter = objectMapper.writerWithView(SimpleInfoView.class);// @2: 設置序列化視圖為SensitiveInfoView(輸出詳細信息)ObjectWriter objectWriter = objectMapper.writerWithView(SensitiveInfoView.class);System.out.println("ObjectWriter中的序列化視圖為: " + objectWriter.getConfig().getActiveView());String JsonResult = objectWriter.writeValueAsString(user);System.out.println(JsonResult);
}

3.4 小結

最后,我本地的項目 SpringBoot 版本是 2.6.13,而我的 Pom 文件依賴中僅僅引入了spring-boot-starter-web,我可以確定的是沒有引入任何 jackson 包的依賴的,而@JsonView 注解是 jackson 包下的注解,那么只有一種可能,那就是對應的 springboot 的 web 依賴集成了對應 jackson 相關 jar 包,出于好奇的我還是點開了 spring-boot-starter-web 依賴,結果發現確實是這樣。
在這里插入圖片描述

4、擴展點

4.1 ResponseBodyAdvice接口

對響應的內容可以進行二次包裝處理,例如對響應參數內容統一進行簽名、加密等邏輯處理。

4.2 RequestBodyAdvice接口

用來對請求的內容進行請求參數重寫處理,例如對接收到請求參數統一進行驗簽、解密等邏輯處理。

綜上所述,相信我們已經掌握了 如何通過一個 DTO 對象來渲染不同需求場景下的 DTO 對象,不過存在唯一的缺點,經過 Debug 調試篇我們可以發現,只有在 序列化的時候才會過濾對應的字段,那么如果一個 DTO 對象的屬性太多,根據類的單一設計原則還是建議使用新建新的 DTO 對象來完成。所以我覺得可以視情況而定,想要代碼的邏輯清晰一些就新建 DTO 實體,想要減少的代碼的編碼量(即減少 DTO 實體對象)那么就用@JsonView注解實現。
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/77605.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/77605.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/77605.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Etcd 壓縮整理

etcd數據存儲 在實際生產中使用 ETCD 存儲元數據,起初集群規模不大的時候元數據信息不多沒有發現什么問題。隨著集群規模越來越大,可能引發存儲問題。 —auto-compaction-retention 由于ETCD數據存儲多版本數據,隨著寫入的主鍵增加歷史版本需…

【更新完畢】2025媽媽杯C題 mathercup數學建模挑戰賽C題數學建模思路代碼文章教學:音頻文件的高質量讀寫與去噪優化

完整內容請看文章最下面的推廣群 我將先給出文章、代碼、結果的完整展示, 再給出四個問題詳細的模型 面向音頻質量優化與存儲效率提升的自適應編碼與去噪模型研究 摘 要 隨著數字媒體技術的迅速發展,音頻處理技術在信息時代的應用愈加廣泛,特別是在存儲…

React-請勿在循環或者條件語句中使用hooks

這是React Hooks的首要規則,這是因為React Hooks 是以單向循環鏈表的形式存儲,即是有序的。循環是為了從最后一個節點移到一個節點的時候,只需通過next一步就可以拿到第一個節點,而不需要一層層回溯。React Hooks的執行&#xff0…

【大模型】 LangChain框架 -LangChain實現問答系統

LangChain 介紹與使用方法 1. 什么是 LangChain?2. LangChain 的主要功能3. 如何使用 LangChain?3.1 環境準備3.2 基本使用示例3.2.1 簡單的問答系統3.2.2 結合外部工具 3.3 高級用法 4. 常見問題及解決方法4.1 安裝問題4.2 運行問題4.3 性能問題 5. 實戰…

企業級HAProxy高可用離線部署實戰(附Kubernetes APIServer負載均衡配置)

企業級HAProxy高可用離線部署實戰(附Kubernetes APIServer負載均衡配置) 摘要:本文深入講解在離線環境下部署HAProxy 3.1.1的全流程,涵蓋源碼編譯、系統服務封裝、K8S APIServer四層負載配置等核心環節,并提供生產級高…

Python網絡爬蟲設計(一)

目錄 一、網絡爬蟲 1、基本的爬蟲 2、獲取URL 3、查找網頁源碼關鍵字 4、代碼實現 二、requests庫 1、requests的優勢和劣勢 2、獲取網頁的其他庫 (1)selenium庫 (2)pyppeteer庫 三、pyppeteer庫 1、pyppeteer庫的來歷…

BR_頻譜20dB 帶寬(RF/TRM/CA/BV-05-C [TX Output Spectrum – 20 dB Bandwidth])

目錄 一、規范要求 1、協議章節 2、測試目的 二、測試方法 1、樣機初值條件: 2、測試步驟: 方法一:頻譜儀 方法二:綜測儀CMW500 3、預期結果 一、規范要求 1、協議章節 4.5.5 RF/TRM/CA/BV-05-C [TX Output Spectrum – 20 dB Ba…

【橘子大模型】初探rag知識庫的構建

一、簡介 我們在實現了一系列功能之后,終于來到了rag的部分,下面我們將基于langchain來實現一個rag檢索。 關于rag方面的知識,可以查看這兩篇文章: 大模型應用之RAG詳解 什么是 RAG(檢索增強生成) 或者是去…

CentOS7執行yum命令報錯 Could not retrieve mirrorlist http://mirrorlist.centos.org

CentOS7執行yum命令報錯 引更新yum源備份原有源創建新的源文件清理并重建緩存 引 CentOS 7 系統無法連接到 CentOS 的官方鏡像站點。這通常是由于網絡問題或 CentOS 7 已停止維護導致的(2024年6月30日后 CentOS 7 已進入 EOL) 報錯明細: 已…

VSCode安裝與環境配置(Mac環境)

20250419 - 概述 大概是非常久之前了,裝了VSCode,估計都得21的時候了,電腦上也沒更新過。當時安裝也直接裝上就完事了。這次把版本更新一下,同時記錄一下這個安裝過程。 安裝 mac下安裝非常簡單,直接從官網下載&am…

QML動畫--ParallelAnimation和SequentialAnimation

一、ParallelAnimation ParallelAnimation 是 QML 中用于并行執行多個動畫的容器動畫類型,可以同時運行多個子動畫。 基本用法 qml import QtQuick 2.15Rectangle {id: rectwidth: 100; height: 100color: "red"x: 0; y: 0; opacity: 1.0ParallelAnim…

NLP高頻面試題(四十三)——什么是人類偏好對齊中的「對齊稅」(Alignment Tax)?如何緩解?

一、什么是「對齊稅」(Alignment Tax)? 所謂「對齊稅」(Alignment Tax),指的是在使人工智能系統符合人類偏好的過程中,所不可避免付出的性能損失或代價。換句話說,當我們迫使AI遵循人類價值觀和規范時,AI系統往往無法達到其最大理論性能。這種性能上的妥協和折衷,就…

速查手冊:TA-Lib 超過150種量化技術指標計算全解 - 1. Overlap Studies(重疊指標)

速查手冊:TA-Lib 超過150種量化技術指標計算全解 - 1. Overlap Studies(重疊指標) TA-Lib(Technical Analysis Library)是廣泛使用的金融技術分析庫,實現了超過150種技術指標計算函數,適用于股票…

重構未來智能:Anthropic 解碼Agent設計哲學三重奏

第一章 智能體進化論:從工具到自主體的認知躍遷 1.1 LLM應用范式演進圖譜 階段技術形態應用特征代表場景初級階段單功能模型硬編碼規則執行文本摘要/分類進階階段工作流編排多模型協同調度跨語言翻譯流水線高級階段自主智能體動態決策交互編程調試/客服對話 1.1.…

Git 中修改某個特定的commit提交內容

在 Git 中修改某個特定的提交(commit)通常需要使用 交互式變基(Interactive Rebase) 或 修改提交(Commit Amend)。以下是不同場景下的具體操作步驟: 一、修改最近的提交(最新提交&am…

ZLMediaKit流媒體服務器

ZLMediaKit 簡介 ZLMediaKit 是一個基于 C11 開發的高性能流媒體服務器框架,支持 RTSP、RTMP、HLS、HTTP-FLV、WebSocket-FLV、HTTP-TS、WebSocket-TS、HTTP-fMP4、WebSocket-fMP4 等多種流媒體協議。 主要特性 多協議支持: 支持 RTSP/RTMP/HLS/HTTP-F…

數字電子技術基礎(五十)——硬件描述語言簡介

目錄 1 硬件描述語言簡介 1.1 硬件描述語言簡介 1.2 硬件編程語言的發展歷史 1.3 兩種硬件描述的比較 1.4 硬件描述語言的應用場景 1.5 基本程序結構 1.5.1 基本程序結構 1.5.2 基本語句和描述方法 1.5.3 仿真 1 硬件描述語言簡介 1.1 硬件描述語言簡介 硬件描述語…

SQL系列:常用函數

1、【MySQL】合并字段函數(列轉行) 它可以將兩個字段中的數據合并到一個字段中。 1)CONCAT函數 CONCAT函數可以將多個字段中的數據合并到一個字段中。它的語法格式如下: SELECT CONCAT(字段1,字段2,...字段N) FROM 表名;SELEC…

多線程和線程同步

多線程在項目開發中使用頻率高,使用多線程能夠提高程序的并發性 提高程序的并發性:1.多線程,對系統資源的消耗更小一些 2.多進程 系統的cpu資源有線,cpu時間片被分好后,由系統進行調度,每個線程在執行的時候都需要搶這個cpu的時間片。如果搶到了,就執行,如果沒搶到,…

時序數據預測:TDengine 與機器學習框架的結合(一)

一、引言 在當今數字化時代,時序數據如潮水般涌來,廣泛存在于物聯網、工業監控、金融交易、氣象監測等眾多領域。這些按時間順序記錄的數據蘊含著豐富的信息,對其進行準確預測,能夠為企業和組織的決策提供有力支持,帶…