解決spring boot中rest介面404,500等錯誤返回統一的json格式

TopCoder.NET發表於2018-01-28

在開發rest介面時,我們往往會定義統一的返回格式,列如:

{
  "status": true,
  "code": 200,
  "message": null,
  "data": [
    {
      "id": "101",
      "name": "jack"
    },
    {
      "id": "102",
      "name": "jason"
    }
  ]
}

但是如果呼叫方請求我們的api時把介面地址寫錯了,就會得到一個404錯誤,在傳統的web系統中我們可自定義404錯誤頁面,展示更友好。

在spring boot中其實也是返回了一個json格式的資料,如下:

{
  "timestamp": 1492063521109,
  "status": 404,
  "error": "Not Found",
  "message": "No message available",
  "path": "/rest11/auth"
}

告訴我們哪個地址是沒找到,其實也挺友好的,但是因為我們上面自定義的資料格式跟下面的不一致,當使用者拿到這個返回的時候是無法識別的,其中最明顯的是status欄位。

我們自定義的是boolean型別,表示是否成功

這邊返回的就是http的狀態碼

所以我們需要在發生這種系統錯誤時也能返回我們自定義的那種格式

定義一個異常處理類

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

@ControllerAdvice
public class GlobalExceptionHandler {
    private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 系統異常處理,比如:404,500
     * @param req
     * @param resp
     * @param e
     * @return
     * @throws Exception
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ResponseData defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
        logger.error("", e);
        ResponseData r = new ResponseData();
        r.setMessage(e.getMessage());
        if (e instanceof org.springframework.web.servlet.NoHandlerFoundException) {
             r.setCode(404);
        } else {
             r.setCode(500);
        }
        r.setData(null);
        r.setStatus(false);
        return r;
    }
}

ResponseData是我們返回格式的實體類

這種在發生錯誤時這邊會捕獲到,然後封裝好返回格式,返回給呼叫方

最後關鍵的一步是在spring boot的配置檔案中加上如下配置:

#出現錯誤時, 直接丟擲異常
spring.mvc.throw-exception-if-no-handler-found=true
#不要為我們工程中的資原始檔建立對映
spring.resources.add-mappings=false

然後我們呼叫一個不存在的介面時,返回的錯誤資訊就是我們自定義的那種格式了

{
  "status": false,
  "code": 404,
  "message": "No handler found for GET /rest11/auth",
  "data": null
}

相關文章