Spring統一格式返回

目錄

一:統一結果返回

1:統一結果返回寫法

2:String類型報錯問題

解決方法

二:統一異常返回

統一異常返回寫法

三:總結


同志們,今天咱來講一講統一格式返回啊,也是好久沒有講過統一格式返回了,說實話這個統一格式返回就是一個讓咱返回的數據能有一個統一的格式嘛,不為別的就為了和你一塊共事的同事不會提著刀追著你滿大街跑,要跟你交流交流工作經驗。

前端:我這數據咋老是對不上啊?

后端:奧兄弟,這個接口我返回的是Boolean類型

前端:我這數據怎么又對不上了啊?

后端:奧好兄弟,我覺得Boolean類型太丑了我就換成String類型了,我覺得它順眼點。

前端:

那咱肯定不能讓同事追著我們交流經驗啊,所以我們一定要讓咱返回的數據能有一個統一的格式

一:統一結果返回

1:統一結果返回寫法

定義返回模板

想要統一返回一個結果,就肯定要有一個返回結果的模板這里我們用Result類來定義

下面代碼中有Result有三個屬性,狀態碼,錯誤信息,返回的數據,三個方法分別是成功時返回,和失敗時返回。

@Data
public class Result<T> {private Integer code;//后端響應狀態碼,成功200,失敗-1,-2表示未登錄private String errmsg;//后端發生錯誤的原因private T data;//每個接口返回的類型(BookInfo,boolean之類的,類型不固定所以要用泛型)/** 成功時設置* */public  static<T> Result<T> success(T data){//泛型方法加static需要加上<T>Result result = new Result<>();result.setData(data);result.setCode(200);return result;}/*失敗時設置* */public  static<T> Result<T> fail(String errMsg){Result result = new Result<>();result.setCode(-1);result.setErrmsg(errMsg);return result;}public  static<T> Result<T> fail(T data,String errMsg){Result result = new Result<>();result.setData(data);result.setCode(-1);result.setErrmsg(errMsg);return result;}
}

實現ResponseBodyAdvice接口并重寫方法,再加上@ControllerAdvice注解

@ControllerAdvice:這個注解的作用就是標記這個類為全局控制器增強類

@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {@Overridepublic boolean supports(MethodParameter returnType, Class converterType) {return true;}@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {return Result.success(body);//返回封裝后結果結果}
}

support()方法:

作用:

supports 方法用于判斷是否需要對某個返回值進行處理,返回true就是處理,返回false就是不處理

參數解析:

returnType:這個參數就是表示控制器方法(Controller類)的返回類型信息,它封裝的有方法的返回參數的詳細信息,比如方法本身,方法所屬的類,返回的類型等等...可以根據這些信息來決定是否要對返回值進行處理,返回對應的true或false

Class converterType:這個參數的意思就是用于將響應體對象,轉換為,HTTP響應消息的那個消息轉換器的類型,后面我們會說到,先按下不表

beforeBodyWrite()方法:

作用:

我們直譯一下這個方法的名字是:寫 body 之前 ,意思就是在控制器方法返回之前進行的處理

當support方法返回true之后,beforeBodyWrite()方法就需要對返回值進行一些處理

參數解析:

Object body:該參數表示控制器方法實際返回的響應體對象

MethodParameter returnType:同supports方法中的returnType

?MediaType selectedContentType:表示響應的類型,如application/json

?Class selectedConverterType:表示用于將響應體對象轉換為 HTTP 響應的消息轉換器的類型

?request和response:這個我們很熟悉,就是代表Http的請求和響應

我們定義幾個簡單的控制器類

@RestController
public class Controller {@RequestMapping("/t1")public int t1(){return 1;}@RequestMapping("/t2")public Boolean t2(){return true;}@RequestMapping("/t2")public String t3(){return "老皇甫";}
}

然后啟動項目測試發現

t1和t2方法沒問題,都對控制器的返回結果進行了封裝,但是返回String類型的t3卻報錯了,這是為什么呢?

?

2:String類型報錯問題

首先明確一點,這個報錯的原因是類型不匹配問題,報的是ClassCastException

我黃色框框里面框的翻譯一下就是Result類型和String類型不匹配,那么為什么呢?

還記得我在解釋方法的參數的時候那個先按下不表的Class converterType?參數嗎?converterType的意思是轉換器類型,SpringMVC默認會注冊?些?帶的 HttpMessageConverter(Http消息轉換器),它是以鏈表的形式組織的,它們的順序是

 ByteArrayHttpMessageConverter()->StringHttpMessageConverter()
->SourceHttpMessageConverter<>()->AllEncompassingFormHttpMessageConverter()

?其中這個AllEncompassingFormHttpMessageConverter()是根據項目的依賴情況來添加對應的轉換器的,如果我們添加了Jackson依賴一般會添加MappingJackson2HttpMessageConverter()轉換器到消息轉換器鏈表的末尾

Spring會根據返回的數據類型, 從 messageConverters 鏈(就是那個鏈表)選擇 合適的消息轉換器?.
當返回的數據是?字符串時, 使?的 MappingJackson2HttpMessageConverter 寫?返回對象(那個在鏈表末尾的消息轉換器)
.
當返回的數據是字符串時 StringHttpMessageConverter 會先被遍歷到,這時會認為
StringHttpMessageConverter 可以使?,然后就會用StringHttpMessageConverter

我們下面調用的堆棧信息中也發現,最后AbstractMessageConverterMethodProcessor調用的也是StringHttpMessageConverter

這里是AbstractMessageConverterMethodProcessor中的邏輯,body在經過beforeBody方法包裝過之后,就會從String類型變為Result類型,但現在匹配到的還是StringHttpMessageConverter 消息轉換器

我們點進去這個?StringHttpMessageConverter 的write方法中看一下(點擊那個由AbstractHttpMessageConverter實現的

)發現里面有一個addDefaultHeader方法(由?StringHttpMessageConverter實現的),再點進去這個方法,發現這個方法接收到的是String參數,但在上面的我們在beforBodyWrite方法中已經將參數轉換為了Result類型,所以才會報出類型不匹配異常

解決方法

既然是因為參數不匹配導致的錯誤,那就只需要將參數搞成匹配的就行了,如下圖所示,如果返回的是字符串類型,那么就將返回類型序列化成字符串類型,而不是Result類型
?

我知道同志們有時候看源碼很懵,不知道哪個調用哪個,這里可以說一下在控制臺打印的日志中,調用的順序一般就是下面的調用上面的,一層一層的,Spring的調用鏈幾乎都有十幾層,所以看的很懵是很正常的?

二:統一異常返回

還有一個問題,不知道同志們發現沒有,就是上面我們在由于String類型不匹配報錯的時候哪個返回結果狀態碼竟然還是200,但這個200可是成功的狀態碼,這都報錯了,那狀態碼肯定能是200啊,所以這個返回結果肯定是不正確的。

統一異常返回寫法

這時候我們就需要通過統一異常捕獲,構造出另一種返回結果失敗的格式,來返回我們可以用

@ControllerAdvice + @ExceptionHandler 兩個注解來實現
寫法非常簡單,就是加上個@ExceptionHandler后面指定要捕獲哪種類型的異常,然后進行對應的封裝邏輯,Exception你也可以進行自定義異常,來滿足你不同的項目需求
因為我們希望給客戶端返回的是數據類型,而不是一個視圖,所以要加上@ResponseBody注解
@ControllerAdvice
@ResponseBody
public class ExceptionAdvice {@ExceptionHandler(Exception.class)//捕獲所有異常public Result handleException(Exception e) {return Result.fail(e.getMessage()+"異常");}@ExceptionHandler(Error.class)//捕獲error類型public Result handleError(Error e) {return Result.fail(e.getMessage()+"錯誤");}@ExceptionHandler(RuntimeException.class)//捕獲運行時異常public Result handleRuntimeException(RuntimeException e) {return Result.fail(e.getMessage()+"運行時異常");}@ExceptionHandler(NullPointerException.class)//捕獲空指針異常public Result handleNullPointerException(NullPointerException e) {return Result.fail(e.getMessage()+"空指針異常");}}

我們來認為制造幾個異常

查看測試結果

狀態碼為-1,返回結果符合預期

三:總結

這篇我們說的也不多,大概就是說了一下

為什么要進行統一的格式返回,

然后統一格式返回的寫法

再是String類型會報錯的問題以及源碼級別的原因,

然后是統一異常返回問題

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

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

相關文章

【無標題】四色拓撲模型與宇宙歷史重構的猜想框架

### 四色拓撲模型與宇宙歷史重構的猜想框架 --- #### **一、理論基礎&#xff1a;四色拓撲與時空全息原理的融合** 1. **宇宙背景信息的拓撲編碼** - **大尺度結構網絡**&#xff1a;將星系團映射為四色頂點&#xff0c;纖維狀暗物質結構作為邊&#xff0c;構建宇宙尺度…

藍橋杯 封閉圖形個數

藍橋杯 封閉圖形個數 題目 鏈接 解答 # 數字個數 n int(input()) # 數字 ls input().split() # 統計數字的圈數 o_nums {} for i, x in enumerate(ls):o_num 0for c in x:if int(c) in [0, 4, 6, 9]:o_num 1elif c 8:o_num 2o_nums[i] o_num # 字典根據圓圈數排序 …

基于javaweb的SpringBoot學生在線考試管理系統設計和實現(源碼+文檔+部署講解)

技術范圍&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬蟲、數據可視化、小程序、安卓app、大數據、物聯網、機器學習等設計與開發。 主要內容&#xff1a;免費功能設計、開題報告、任務書、中期檢查PPT、系統功能實現、代碼編寫、論文編寫和輔導、論…

國產編輯器EverEdit - 超多樣式設置

1 設置-編輯-樣式 1.1 設置說明 1.1.1 折疊樣式 默認為箭頭&#xff0c;折疊樣式選項如下&#xff1a; 箭頭&#xff1a; 矩形和線條 五邊形 圓形圖標 1.1.2 光標樣式 光標用于指示當前用戶輸入位置&#xff0c;光標樣式選項如下&#xff1a; 默認 纖細 字寬 …

Linux - 線程控制

一、線程概念 1&#xff09;線程地址空間 線程與進程共享相同的虛擬地址空間&#xff0c;因此線程在訪問內存時與進程沒有本質的區別。但線程共享和獨占的內存區域有不同的特點&#xff0c;理解這些特性對于正確使用線程至關重要。 1. 線程地址空間的組成 線程的地址空間是…

通過多線程分別獲取高分辨率和低分辨率的H264碼流

目錄 一.RV1126 VI采集攝像頭數據并同時獲取高分辨率碼流和低分辨率碼流流程 ?編輯 1.1初始化VI模塊&#xff1a; 1.2初始化RGA模塊&#xff1a; 1.3初始化高分辨率VENC編碼器、 低分辨率VENC編碼器&#xff1a; 1.4 VI綁定高分辨率VENC編碼器&#xff0c;VI綁定RGA模塊…

部署RabbitMQ集群詳細教程

部署RabbitMQ集群詳細教程 下面是一份在 Ubuntu 環境下部署 RabbitMQ 集群的詳細步驟說明&#xff0c;涉及主機名設置、Erlang & RabbitMQ 安裝、管理插件啟用、集群通信 Cookie 配置、節點加入集群、鏡像隊列策略設置以及集群驗證等。為了演示方便&#xff0c;以下示例假…

【Linux】之【Bug】VMware 虛擬機開機 一直卡在黑屏左上角下劃線閃爍界面

解決 參考&#xff1a; 解決Ubuntu20.04 開機黑屏光標閃爍進不去系統 Centos根目錄100%解決思路 當前界面 ctrlaltf3-f6 暫時進入終端界面 df -h 查看發現根目錄 磁盤空間已滿 執行命令 查看當前目錄占用內存明細 sudo du -h -x --max-depth1清理無用的大內存文件 或者安裝…

webflux集成langchain4j基礎版

伴隨著大模型應用的興起&#xff0c;webflux逐漸引起關注。為了以java的方式運行AI應用&#xff0c;讓我們一起學習webflux集成langchain4j吧。 1. 項目依賴 首先&#xff0c;你需要在 pom.xml 中添加必要的依賴&#xff1a; <dependencies><!-- Spring WebFlux --…

使用GitLink個人建站服務部署Allure在線測試報告

更多技術文章&#xff0c;訪問軟件測試社區 文章目錄 &#x1f680;前言&#x1f511;開通GitLink個人建站服務1. 前提條件2. 登錄GitLink平臺&#xff08;https://www.gitlink.org.cn/login&#xff09;3. 進入設置>個人建站>我的站點4. 新建站點5. 去倉部進行部署6. 安…

go數組的聲明和初始化

1.數組簡介 數組是可以存放多個同一類型的數據。數組也是一種數據類型&#xff0c;在go中&#xff0c;數組是值類型。數組的長度也是數組類型的一部分&#xff0c;所以[2]int和[3]int屬于不同的數據類型。 2.數組的長度也是類型的一部分 var arr1 [2]intvar arr2 [3]intfmt.P…

四款GIS工具箱軟件解析:滿足企業多樣化空間數據需求

概述 隨著地理信息系統&#xff08;GIS&#xff09;在城市規劃、環境監測、資源管理等領域的廣泛應用&#xff0c;各種GIS工具箱軟件不斷涌現&#xff0c;為用戶提供了強大的數據處理、空間分析和地圖制圖功能。本文將為大家介紹4款GIS工具箱軟件&#xff0c;這些軟件各具特色…

VirtualBox虛擬機安裝Mac OS啟動后的系統設置

VirtualBox虛擬機安裝Mac OS一直沒裝成功&#xff0c;本來想要放棄的&#xff0c;后來想著再試一次&#xff0c;于是在關機的情況&#xff0c;執行那幾句設置&#xff1a; cd "E:\Program Files\Oracle\VirtualBox\" VBoxManage.exe modifyvm "MacOS" --c…

[力扣每日一練]關于所有不同域名的查找

一、題目要求&#xff1a; 表&#xff1a;Emails---------------------- | Column Name | Type | ---------------------- | id | int | | email | varchar | ---------------------- id 是這張表的主鍵&#xff08;有不同值的列&#xff09;。 這張表的…

blender看不到導入的模型

參考&#xff1a;blender 快捷鍵 常見問題_blender材質預覽快捷鍵-CSDN博客 方法一&#xff1a;視圖-裁剪起點&#xff0c;設置一個很大的值 方法二&#xff1a;選中所有對象&#xff0c;對齊視圖-視圖對齊活動項-選擇一個視圖

HarmonyOS Next~鴻蒙系統ArkCompiler跨平臺編譯技術的革新實踐

HarmonyOS Next~鴻蒙系統ArkCompiler跨平臺編譯技術的革新實踐 引言 在萬物互聯時代&#xff0c;操作系統對編譯技術的需求已從單純的代碼轉換演變為跨設備協同、高效資源調度與極致性能優化的綜合挑戰。華為鴻蒙系統&#xff08;HarmonyOS&#xff09;自主研發的ArkCompiler…

Kanna 與 Swift:結合使用提升網絡請求效率

Kanna 是一個基于 Swift 的輕量級、高性能的 XML/HTML 解析庫&#xff0c;它能夠幫助開發者快速解析和處理網絡返回的 HTML 或 XML 數據。通過結合 Kanna 和 Swift 的網絡請求功能&#xff0c;我們可以構建更加高效、靈活的網絡交互模塊。本文將詳細介紹如何在 Swift 中使用 Ka…

《大語言模型的原理發展與應用》:此文為AI自動生成

《大語言模型的原理發展與應用》&#xff1a;此文為AI自動生成 一、引言&#xff1a;大語言模型&#xff0c;AI 時代的 “新引擎” 在當今數字化浪潮中&#xff0c;大語言模型宛如一顆璀璨的明星&#xff0c;照亮了人工智能發展的道路&#xff0c;成為推動各領域變革的核心驅…

RabbitMQ消息隊列 面試專題

RabbitMQ消息隊列 面試專題 RabbitMQ的實現原理為什么需要消息隊列常見消息隊列比較如何保證消息不丟失如何防止消息重復消費如何保證消息的有序性如何處理消息堆積 RabbitMQ的實現原理 RabbitMQ 是一個基于 AMQP&#xff08;Advanced Message Queuing Protocol&#xff09; 協…

【Hudi-SQL DDL創建表語法】

CREATE TABLE 命令功能 CREATE TABLE命令通過指定帶有表屬性的字段列表來創建Hudi Table。 命令格式 CREATE TABLE [ IF NOT EXISTS] [database_name.]table_name[ (columnTypeList)]USING hudi[ COMMENT table_comment ][ LOCATION location_path ][ OPTIONS (options_lis…