對於Http Status Code,我有話說

如今不少項目都是web項目,先後端分離,惟一的交互就是經過restful接口,而當咱們請求返回的時候,status code如何返回呢?前端

首先介紹下經常使用的http status code有哪些。java

2XX(Success 成功狀態碼)

200 - OK

請求成功web

201 - Created

文檔建立成功,好比新增一個user成功面試

202 - Accepted

請求已被接受,但相應的操做可能還沒有完成。這用於後臺操做,例如數據庫壓縮等異步操做spring

4XX(Client Error 客戶端錯誤狀態碼)

400 - Bad Request

請求參數有誤(好比應該傳一個Number類型的參數,你卻傳了一個字符串),請求沒法被服務器理解,修改後能夠從新提交這個請求數據庫

401 - Unauthorized

當前請求用戶未被受權,好比未登錄json

403 - Forbidden

當前請求被拒絕。好比文件系統訪問權限有問題,或者進行了越權操做(好比普通用戶試圖獲取admin用戶列表)後端

404 - Not Found

沒法找到請求資源,通常是url錯誤api

405 - Method Not Allowed

使用無效的HTTP請求類型對請求的URL進行了請求。好比某個api只支持post,而client卻使用了get服務器

406 - Not Acceptable

服務器不支持請求的content type

413 - Request Entity Too Large

請求體太大不支持,通常是上傳的文件超出了限定致使的。

5XX(Server Error 服務器錯誤狀態碼)

500 - Internal Server Error

表示服務端在執行請求時發生了錯誤。 多是服務器或者應用存在bug

503 - Service Unavailable

服務不可用,如今沒法處理請求。

返回什麼樣的錯誤碼

通常在restful API裏,咱們對於狀態碼的認定是這樣的:

1. 2xx: server 收到 client 端請求,能夠執行
2. 4xx: client 送來資料有錯,server 端沒法執行 (client 修正錯誤後,可再送一次請求)
3. 5xx: client 送來的資料沒錯,但 server 端出錯沒法執行(client 端沒法 take 任何 action)

可是我也見過status code返回200,而後在response中經過自定義code告訴用戶請求是否成功

{
  "code"10020,
  "msg""name不能爲空"
}
複製代碼

雖然蘿蔔青菜各有所愛,我我的仍然認爲對於REST接口,就應該用HTTP層面的status來表達操做是否成功。,由於網絡通信不只僅是一個客戶端一個服務器的事情,中間會有不少層節點,若是其中某一層對status 200的請求理解很是正統,作了cache或者什麼處理,那你可能就坐蠟了。並且既然是寫接口,就最好標準一點,別給本身埋坑。

因此對於成功的請求就應該返回2XX,對於4XX接口,你能夠作對應的封裝

返回數據
返回數據

狀態碼必定要返回4XX,可是你能夠在reponse data中返回異常錯誤碼(這個錯誤碼是業務錯誤的錯誤碼),這個時候能夠和前端約定好這個業務錯誤碼錶明什麼意思,就能夠給用戶相應的提示了。

返回的數據格式

public class BaseResponse<T{

    // 業務異常碼
    private int code;

    // 說明信息
    private String msg;

    // 須要封裝返回的數據
    private T data;
}
複製代碼

好比對於GET /api/users/1,這樣的請求返回的數據就放在data這個字段當中。

{
  "code":200,
  "msg":"SUCCESS",
  "data": {
    "id":1095,
    "name":"張三"
  }
}
複製代碼

而對於請求失敗的錯誤(http status code是4XX),則是會返回下面的數據

{
  "code"10030,
  "msg""id不存在"
}
複製代碼

Spring對Http Status Code的支持

@ResponseStatus(HttpStatus.CREATED)
public BaseResponse addUser(UserParam userParam) {

    return service.addUser(userParam);
}
複製代碼

能夠直接經過ResponseStatus註解來指定返回的錯誤碼是多少。固然上面說的是正常狀況,那些參數失敗校驗失敗或者是其餘業務異常致使的狀況如何處理呢?

有兩種辦法,第一種是經過Spring的 ResponseEntity 這個類來完成

public ResponseEntity<BaseResponse> addUser(UserParam userParam) {

  if(validate(userParam)) {
      return service.addUser(userParam);
  }

  return  new ResponseEntity<>(ResponseUtil.fail(STATUS_INVALID_PARAM), HttpStatus.NOT_FOUND);
}
複製代碼

第二種方式是藉助全局異常處理,若是在service中發現客戶端傳遞過來的參數存在問題,能夠經過拋出異常,而後在全局異常攔截器中進行統一處理

@RestControllerAdvice
public class WebExceptionConfig {

  @ExceptionHandler(InvalidParamException.class)
  @ResponseStatus(HttpStatus.BAD_REQUEST)
  public BaseResponse handleInvalidParamException(InvalidParamException e) {
      return ResponseUtil.fail(STATUS_INVALID_PARAM, e.getMessage());
  }
}
複製代碼

總結

  1. 不一樣的狀況返回不一樣的status code,對於失敗的請求,請返回4XX,並能夠經過返回數據指定業務異常code
  2. 內部必定要統一
  3. 不要讓返回的status code影響你的業務邏輯

點關注,不迷路

若是以爲我寫的還行的話,請給我個點贊、關注、分享呀,對我是很大的激勵呀。

公衆號 think123,能夠第一時間閱讀喲。

往期回顧

嘿,我用Drone作CI

和麪試官這樣吹MongoDB複製集

知道了這些 MongoDB設計技巧,提高效率50%

我花了一週讀了Kafka Producer的源碼

面試官:如何用LinkedHashMap實現LRU

我是如何理解Java8 Stream

不再怕面試官問我JDK8 HashMap了

MongoDB中的定時索引

相關文章
相關標籤/搜索