日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

boot返回码规范 spring_SpringBoot 系列 web 篇之自定义返回 Http Code 的 n 种姿势

發布時間:2024/10/12 javascript 83 豆豆
生活随笔 收集整理的這篇文章主要介紹了 boot返回码规范 spring_SpringBoot 系列 web 篇之自定义返回 Http Code 的 n 种姿势 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

200105-SpringBoot 系列 web 篇之自定義返回 Http Code 的 n 種姿勢

雖然 http 的提供了一整套完整、定義明確的狀態碼,但實際的業務支持中,后端并不總會遵守這套規則,更多的是在返回結果中,加一個 code 字段來自定義業務狀態,即便是后端 5xx 了,返回給前端的 http code 依然是 200

那么如果我想遵守 http 的規范,不同的 case 返回不同的 http code 在 Spring 中可以做呢?

本文將介紹四種設置返回的 HTTP CODE 的方式

  • @ResponseStatus 注解方式
  • HttpServletResponse#sendError
  • HttpServletResponse#setStatus
  • ResponseEntity

I. 返回 Http Code 的 n 種姿勢

0. 環境

進入正文之前,先創建一個 SpringBoot 項目,本文示例所有版本為 spring-boot.2.1.2.RELEASE

(需要測試的小伙伴,本機創建一個 maven 項目,在pom.xml文件中,拷貝下面的配置即可)

org.springframework.boot spring-boot-starter-parent 2.2.1.RELEASEUTF-8UTF-81.8org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-maven-plugin spring-snapshotsSpring Snapshotshttps://repo.spring.io/libs-snapshot-localtruespring-milestonesSpring Milestoneshttps://repo.spring.io/libs-milestone-localfalsespring-releasesSpring Releaseshttps://repo.spring.io/libs-release-localfalse

下面所有的方法都放在 ErrorCodeRest 這個類中

@RestController@RequestMapping(path = "code")public class ErrorCodeRest {}

1. ResponseStatus 使用姿勢

通過注解@ResponseStatus,來指定返回的 http code, 一般來說,使用它有兩種姿勢,一個是直接加在方法上,一個是加在異常類上

a. 裝飾方法

直接在方法上添加注解,并制定對應的 code

/** * 注解方式,只支持標準http狀態碼 * * @return */@GetMapping("ano")@ResponseStatus(code = HttpStatus.BAD_REQUEST, reason = "請求參數異常!")public String ano() { return "{"code": 400, "msg": "bad request!"}";}

實測一下,返回結果如下

? ~ curl 'http://127.0.0.1:8080/code/ano' -iHTTP/1.1 400Content-Type: application/json;charset=UTF-8Transfer-Encoding: chunkedDate: Sun, 05 Jan 2020 01:29:04 GMTConnection: close{"timestamp":"2020-01-05T01:29:04.673+0000","status":400,"error":"Bad Request","message":"請求參數異常!","path":"/code/ano"}%

當我們發起請求時,返回的狀態碼為 400,返回的數據為 springboot 默認的錯誤信息格式

雖然上面這種使用姿勢可以設置 http code,但是這種使用姿勢有什么意義呢?

如果看過 web 系列教程中的:SpringBoot 系列教程 web 篇之全局異常處理 可能就會有一些映象,配合@ExceptionHandler來根據異常返回對應的狀態碼

一個推薦的使用姿勢,下面表示當你的業務邏輯中出現數組越界時,返回 500 的狀態碼以及完整的堆棧信息

@ResponseBody@ExceptionHandler(value = ArrayIndexOutOfBoundsException.class)@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)public String handleArrayIndexOutBounds(HttpServletRequest request, HttpServletResponse response, ArrayIndexOutOfBoundsException e) throws IOException { log.info("array index out conf!"); return "aryIndexOutOfBounds: " + getThrowableStackInfo(e);}

b. 裝飾異常類

另外一種使用姿勢就是直接裝飾在異常類上,然后當你的業務代碼中,拋出特定的異常類,返回的 httpcode 就會設置為注解中的值

/** * 異常類 + 注解方式,只支持標準http狀態碼 * * @return */@GetMapping("exception/500")public String serverException() { throw new ServerException("內部異常哦");}@GetMapping("exception/400")public String clientException() { throw new ClientException("客戶端異常哦");}@ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR, reason = "服務器失聯了,請到月球上呼叫試試~~")public static class ServerException extends RuntimeException { public ServerException(String message) { super(message); }}@ResponseStatus(code = HttpStatus.BAD_REQUEST, reason = "老哥,你的請求有問題~~")public static class ClientException extends RuntimeException { public ClientException(String message) { super(message); }}

測試結果如下,在異常類上添加注解的方式,優點在于不需要配合@ExceptionHandler寫額外的邏輯了;缺點則在于需要定義很多的自定義異常類型

? ~ curl 'http://127.0.0.1:8080/code/exception/400' -iHTTP/1.1 400Content-Type: application/json;charset=UTF-8Transfer-Encoding: chunkedDate: Sun, 05 Jan 2020 01:37:07 GMTConnection: close{"timestamp":"2020-01-05T01:37:07.662+0000","status":400,"error":"Bad Request","message":"老哥,你的請求有問題~~","path":"/code/exception/400"}%? ~ curl 'http://127.0.0.1:8080/code/exception/500' -iHTTP/1.1 500Content-Type: application/json;charset=UTF-8Transfer-Encoding: chunkedDate: Sun, 05 Jan 2020 01:37:09 GMTConnection: close{"timestamp":"2020-01-05T01:37:09.389+0000","status":500,"error":"Internal Server Error","message":"服務器失聯了,請到月球上呼叫試試~~","path":"/code/exception/500"}%

注意

  • ResponseStatus 注解的使用姿勢,只支持標準的 Http Code(必須是枚舉類org.springframework.http.HttpStatus)

2. ResponseEntity

這種使用姿勢就比較簡單了,方法的返回結果必須是ResponseEntity,下面給出兩個實際的 case

@GetMapping("401")public ResponseEntity _401() { return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("{"code": 401, "msg": "未授權!"}");}@GetMapping("451")public ResponseEntity _451() { return ResponseEntity.status(451).body("{"code": 451, "msg": "自定義異常!"}");}

實測結果

? ~ curl 'http://127.0.0.1:8080/code/401' -iHTTP/1.1 401Content-Type: text/plain;charset=UTF-8Content-Length: 34Date: Sun, 05 Jan 2020 01:40:10 GMT{"code": 401, "msg": "未授權!"}? ~ curl 'http://127.0.0.1:8080/code/451' -iHTTP/1.1 451Content-Type: text/plain;charset=UTF-8Content-Length: 40Date: Sun, 05 Jan 2020 01:40:19 GMT{"code": 451, "msg": "自定義異常!"}

從上面的使用實例上看,可以知道這種使用方式,不僅僅支持標準的 http code,也支持自定義的 code(如返回 code 451)

3. HttpServletResponse

這種使用姿勢則是直接操作HttpServletResponse對象,手動錄入返回的結果

a. setStatus

/** * response.setStatus 支持自定義http code,并可以返回結果 * * @param response * @return */@GetMapping("525")public String _525(HttpServletResponse response) { response.setStatus(525); return "{"code": 525, "msg": "自定義錯誤碼 525!"}";}

輸出結果

? ~ curl 'http://127.0.0.1:8080/code/525' -iHTTP/1.1 525Content-Type: text/plain;charset=UTF-8Content-Length: 47Date: Sun, 05 Jan 2020 01:45:38 GMT{"code": 525, "msg": "自定義錯誤碼 525!"}%

使用方式比較簡單,直接設置 status 即可,支持自定義的 Http Code 返回

b. sendError

使用這種姿勢的時候需要注意一下,只支持標準的 http code,而且 response body 中不會有你的業務返回數據,如

/** * send error 方式,只支持標準http狀態碼; 且不會帶上返回的結果 * * @param response * @return * @throws IOException */@GetMapping("410")public String _410(HttpServletResponse response) throws IOException { response.sendError(410, "send 410"); return "{"code": 410, "msg": "Gone 410!"}";}@GetMapping("460")public String _460(HttpServletResponse response) throws IOException { response.sendError(460, "send 460"); return "{"code": 460, "msg": "Gone 460!"}";}

輸出結果

? ~ curl 'http://127.0.0.1:8080/code/410' -iHTTP/1.1 410Content-Type: application/json;charset=UTF-8Transfer-Encoding: chunkedDate: Sun, 05 Jan 2020 01:47:52 GMT{"timestamp":"2020-01-05T01:47:52.300+0000","status":410,"error":"Gone","message":"send 410","path":"/code/410"}%? ~ curl 'http://127.0.0.1:8080/code/460' -iHTTP/1.1 500Content-Type: application/json;charset=UTF-8Transfer-Encoding: chunkedDate: Sun, 05 Jan 2020 01:47:54 GMTConnection: close{"timestamp":"2020-01-05T01:47:54.719+0000","status":460,"error":"Http Status 460","message":"send 460","path":"/code/460"}%

從上面的 case 也可以看出,當我們使用 send error 時,如果是標準的 http code,會設置對響應頭;如果是自定義的不被識別的 code,那么返回的 http code 是 500

4, 小結

上面介紹了幾種常見的設置響應 http code 的姿勢,下面小結一下使用時的注意事項

ResponseStatus

  • 只支持標準的 http code
  • 裝飾自定義異常類,使用時拋出對應的異常類,從而達到設置響應 code 的效果 缺點對非可控的異常類不可用
  • 結合@ExceptionHandler,用來裝飾方法

ResponseEntity

形如:

return ResponseEntity.status(451).body("{"code": 451, "msg": "自定義異常!"}");
  • 我個人感覺是最強大的使用姿勢,就是寫起來沒有那么簡潔
  • 支持自定義 code,支持設置 response body

HttpServletResponse

  • setStatus: 設置響應 code,支持自定義 code,支持返回 response body
  • sendError: 只支持標準的 http code,如果傳入自定義的 code,返回的 http code 會是 500

II. 其他

項目源碼

  • 工程:https://github.com/liuyueyi/spring-boot-demo[1]
  • 項目:https://github.com/liuyueyi/spring-boot-demo/blob/master/spring-boot/207-web-response[2]

1. 一灰灰 Blog

盡信書則不如,以上內容,純屬一家之言,因個人能力有限,難免有疏漏和錯誤之處,如發現 bug 或者有更好的建議,歡迎批評指正,不吝感激

下面一灰灰的個人博客,記錄所有學習和工作中的博文,歡迎大家前去逛逛

  • 一灰灰 Blog 個人博客 https://blog.hhui.top[3]
  • 一灰灰 Blog-Spring 專題博客 http://spring.hhui.top[4]

總結

以上是生活随笔為你收集整理的boot返回码规范 spring_SpringBoot 系列 web 篇之自定义返回 Http Code 的 n 种姿势的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。