學習springBoot 進階統一異常處理(六)
在實際開發當中我們經常會遇到BUG,所以都會封裝一個異常返回類來使用,提示我們到底是那一步出了問題,方便於我們追蹤問題並且解決問題,
以下舉個新增女孩物件為例子,當新增的女孩物件年齡小於10歲時我們提示該女孩在上小學,大於10歲且小於16歲提示可能在上初中,通過例子說明我們如何對異常統一處理並返回提示結果的
在domain包下新增一個Result類
Result類
package com.zhang.domain; /** * http請求返回的最外層物件 * @author Administrator * */ public class Result<T> { /** * 錯誤碼 */ private Integer code; /** * 提示資訊 */ private String msg; /** * 具體的內容 */ private T data; public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public T getData() { return data; } public void setData(T data) { this.data = data; } }
修改GirlController類中的tian新增女孩物件方法
/** * 新增一個女孩 */ @PostMapping(value="/girlsAdd") public Result<Girl> girlAdd(@Valid Girl girl , BindingResult bindingResult){ if(bindingResult.hasErrors()){ Result result = new Result(); result.setCode(1); result.setMsg(bindingResult.getFieldError().getDefaultMessage()); return result; } girl.setCupSize(girl.getCupSize()); girl.setAge(girl.getAge()); Result result = new Result(); result.setCode(0); result.setMsg("成功!"); result.setData(girlRepository.save(girl)); return result; }
修改完成啟動專案看看之前整合的Result類有沒有成功
Postman 呼叫新增女孩物件的方法 成功返回外層結果物件整合Result類
對於返回結果我們會頻繁使用,所以我們對於返回結果在封裝成一個公共類方便以後呼叫
建立utils包,ResultUtil類
ResultUtil 類
package com.zhang.utils; import com.zhang.domain.Result; /** * 返回結果工具類 * @author Administrator * */ public class ResultUtil { public static Result success(Object object){ Result result = new Result(); result.setCode(0); result.setMsg("成功"); result.setData(object); return result; } public static Result success(){ return success(null); } public static Result error(Integer code,String msg){ Result result = new Result(); result.setCode(code); result.setMsg(msg); return result; } }
GirlController 類中的新增女生物件方法也修改一下
/**
* 新增一個女孩
*/
@PostMapping(value="/girlsAdd")
public Result<Girl> girlAdd(@Valid Girl girl , BindingResult bindingResult){
if(bindingResult.hasErrors()){
return ResultUtil.error(1, bindingResult.getFieldError().getDefaultMessage());
}
girl.setCupSize(girl.getCupSize());
girl.setAge(girl.getAge());
return ResultUtil.success(girl);
}
Postman 呼叫新增女孩物件的方法 整合ResultUtil類
下面繼續接著完善開題我們說的按照年齡來判斷要返回的結果
當新增的女孩物件年齡小於10歲時我們提示該女孩在上小學,大於10歲且小於16歲提示可能在上初中
GirlService 類 新增處理邏輯的方法
/**
* 統一丟擲異常讓封裝好的異常類返回封裝好的值到也頁面中
* @param id
* @throws Exception
*/
public void getAge(Integer id ) throws Exception{
Girl girl = girlRepository.findOne(id);
Integer age = girl.getAge();
if(age<10){
throw new Exception("你還在上小學");
}else if(age>10 && age<16){
throw new Exception("你還在上初中");
}
}
GirlController 類新增一個查詢的方法 呼叫GirlService 類中處理邏輯的方法
@GetMapping(value="grils/getAge/{id}")
public void getAge(@PathVariable("id") Integer id) throws Exception {
girlService.getAge(id);
}
建立Handle包 和 ExceptionHandle類
ExceptionHandle類
package com.zhang.Handle;
import javax.xml.ws.RespectBinding;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import com.zhang.domain.Result;
import com.zhang.utils.ResultUtil;
/**
* 捕捉異常類
* @author Administrator
*
*/
@ControllerAdvice
public class ExceptionHandle {
@ExceptionHandler(value=Exception.class)
@ResponseBody
public Result handle(Exception e){
return ResultUtil.error(100, e.getMessage());
}
}
Postman 呼叫新增女孩物件的方法 整合ExceptionHandle類 統一異常處理整合成功,但是現實開發中我們還想要具體知道是在那一個環節報錯的,那就繼續在封裝一下
具體知道是在那一個環節報錯的,那就繼續在封裝一下 讓我們報錯帶上指定編號,這樣我們就很快可以判斷是哪裡環節出了問題
建立 exception包 GrilException類
GrilException類
package com.zhang.exception;
public class GrilException extends RuntimeException {
private Integer code;
public GrilException(Integer code , String message) {
super(message);
this.code = code;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
}
GirlService 類中 getAge方法修改一下
/**
* 統一丟擲異常讓封裝好的異常類返回封裝好的值到也頁面中
* @param id
* @throws Exception
*/
public void getAge(Integer id ) throws Exception{
Girl girl = girlRepository.findOne(id);
Integer age = girl.getAge();
if(age<10){
throw new GrilException(100,"你還在上小學");
}else if(age>10 && age<16){
throw new GrilException(101,"你還在上初中");
}
}
ExceptionHandle 類 修改一下
private final static Logger logger= org.slf4j.LoggerFactory.getLogger(HttpAspect.class);
@ExceptionHandler(value=Exception.class)
@ResponseBody
public Result handle(Exception e){
//判斷一下異常是不是返回的我們定義的
if(e instanceof GrilException){
GrilException grilException = (GrilException) e;
return ResultUtil.error(grilException.getCode(), grilException.getMessage());
}else{
logger.info("【系統異常】{}",e);
return ResultUtil.error(-1, "未知錯誤!!!");
}
}
Postman 呼叫新增女孩物件的方法 整合GrilException類成功 返回code是我們指定的101 這樣就有助於我們對異常的指定位置
如果是系統異常報錯誤,我們可以用日誌記錄起來方便我們判斷
針對於實際開發當中是多人開發,編號會寫重複,所以我們就在建立一個列舉類來統一管理我們 的編號避免重複
建立enums 包 ResultEnum類
ResultEnum 類
package com.zhang.enums;
/**
* 管理編號的列舉類
* @author Administrator
*
*/
public enum ResultEnum {
UNKONW_ERROR(-1,"未知錯誤"),
SUCCCESS(0,"成功"),
PRIMARY_SCHOOL(100,"你可能上小學"),
MIODLE_SCHOOL(101,"你可能上初中"),
;
private Integer code;
private String msg;
private ResultEnum(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public Integer getCode() {
return code;
}
public String getMsg() {
return msg;
}
}
GirlService 類呼叫列舉類的方法
/**
* 統一丟擲異常讓封裝好的異常類返回封裝好的值到也頁面中
* @param id
* @throws Exception
*/
public void getAge(Integer id ) throws Exception{
Girl girl = girlRepository.findOne(id);
Integer age = girl.getAge();
if(age<10){
throw new GrilException(ResultEnum.PRIMARY_SCHOOL);
}else if(age>10 && age<16){
throw new GrilException(ResultEnum.MIODLE_SCHOOL);
}
}
GrilException 類中構造器方法修改
package com.zhang.exception;
import com.zhang.enums.ResultEnum;
/**
* 異常類
* @author Administrator
*
*/
public class GrilException extends RuntimeException {
private Integer code;
public GrilException(ResultEnum resultEnum) {
super(resultEnum.getMsg());
this.code = resultEnum.getCode();
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
}
Postman 呼叫新增女孩物件的方法 整合ResultEnum類成功