前言
在設計Restful 風格API時,如何進行錯誤響應旺矾,也是一個重要的環(huán)節(jié)蔑鹦。我在實踐中發(fā)現(xiàn),如果可以統(tǒng)一封裝錯誤響應箕宙,那么會給調(diào)用者帶來很大的便利嚎朽。下面就來說說使用Spring Boot框架時,如何進行統(tǒng)一的錯誤響應柬帕。
在Spring Boot項目中有3種級別的異常處理:
- 全局的錯誤處理
- Controller的錯誤處理
- 具體方法中的try/catch處理
為了演示如何使用上面的方式進行錯誤處理哟忍,我們假定擁有三個類
- BaseException 其它自定義異常類的父類
- CustomException1 繼承自BaseException
- CustomException2 繼承自BaseException
我們會創(chuàng)建以下幾種方法,來觸發(fā)不同的異常
- ex1() throws BaseException
- ex2() throws CustomException1
- ex3() throws CustomException2
- ex4() throws NullPointerException
- ex5() throws NumberFormatException
接著我們來看如何使用上面提到的處理流程來處理不同的異常陷寝。
我們創(chuàng)建一個類锅很,用 **@ControllerAdvice **和 @RestController修飾。 這表明本類可以返回一個Rest的響應凤跑。
@ControllerAdvice 表明本類會進行應用全局的異常處理粗蔚。
@RestController 表明本類是一個Controller
使用 @ExceptionHandler 注解 定義需要捕獲的異常類. (基類異常會捕獲派生類異常)
用可以通過使用 @ResponseStatus 注解來修改響應的返回狀態(tài)。
** HomeController.class **
<pre>
package com.ekiras.controller;
import com.ekiras.exception.BaseException;
import com.ekiras.exception.CustomException1;
import com.ekiras.exception.CustomException2;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
@author ekansh
-
@since 19/2/16
*/
@RestController
@RequestMapping({"","/"})
public class HomeController {@RequestMapping("/ex1")
public String ex1(){
// 被全局的異常捕獲方法 handleBaseException 捕獲
throw new BaseException("Base Exception");
}@RequestMapping("/ex2")
public String ex2(){
// 被全局的異常捕獲方法 handleCustomException1 捕獲
throw new CustomException1();
}@RequestMapping("/ex3")
public String ex3(){
// 被全局的異常捕獲方法 handleBaseException 捕獲
throw new CustomException2();
}@RequestMapping("/ex4")
public String ex4(){
// 被全局的異常捕獲方法 handleBaseException 捕獲
throw new NullPointerException("null pointer exception");
}@RequestMapping("/ex5")
public String ex5(){
// 被Controller級的異常捕獲方法 nfeHandler 捕獲
throw new NumberFormatException("number format exception");
}/**
- This method will handle all the Number Format Exceptions that arise within this controller.
- */
@ExceptionHandler(value = NumberFormatException.class)
public String nfeHandler(NumberFormatException e){
return e.getMessage();
}
}
</pre>
GlobalExceptionHandler.class
<pre>
package com.ekiras.handler.exception;
import com.ekiras.exception.BaseException;
import com.ekiras.exception.CustomException1;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
/**
@author ekansh
-
@since 19/2/16
*/
@ControllerAdvice
@RestController
public class GlobalExceptionHandler {@ExceptionHandler(value = CustomException1.class)
public String handleCustomException1(CustomException1 e){
return e.getMessage();
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(value = BaseException.class)
public String handleBaseException(BaseException e){
return e.getMessage();
}
@ExceptionHandler(value = Exception.class)
public String handleException(Exception e){return e.getMessage();}
}
</pre>
結論:
-
handleCustomException1(CustomException1 e)
會捕獲所有來自CustomException1的異常饶火。 -
handleBaseException(BaseException e)
會捕獲所有來自BaseException and CustomException2的異常鹏控。 - **handleException(Exception e) :: **
會捕獲所有派生自Exception 類的異常 - 如果有更接近異常類的異常處理方法,那么異常由其優(yōu)先捕獲肤寝,否則繼續(xù)向上查找当辐。
- 我們可以使用全局的異常處理流程來捕獲異常進行統(tǒng)一格式的錯誤響應。
參考
http://www.ekiras.com/2016/02/how-to-do-exception-handling-in-springboot-rest-application.html