第一篇, SpringBoot #1:spring boot集成swagger2 & spring-data-jpa & logging
第二篇, SpringBoot #2:spring boot集成Redis緩存
第三篇, SpringBoot #3:spring boot集成spring-boot-starter-security & jjwt實現權限驗證
? 用SprintBoot做了RESTful風格的基礎框架,但發現了個問題,如果服務在處理業務時發現了異常怎么處理呢,舉個栗子,在獲取一個城市的詳細信息時發現傳和的城市編號不存在,我是返回200在返回的數據里說傳入的編號不存在呢,還是直接拋出異常給前端?對于純RESTful風格的服務,我更傾向于拋出異常到前端。這里就來講講怎么來拋出這個異常,讓前端能獲取到有用的信息,而不只是一個500錯誤。
? 首先我把異常分為兩種,一種是可控制的,或者是由我們發現條件不正確主動拋出的異常,就像前城市編號不存在那個粟子;另一種是不可控制的,或者說是程序存在bug引起的異常,但這種異常也不想變態的就直接給前端拋出個500異常。
實現步驟如下:
第1步,新建一個Exception類
? 新建一個RESTException類,在主動招聘異常時,就拋出一個RESTException類實例。它包含兩個屬性,code和message。code是要拋出的異常代碼用http狀態碼來表示,message是想要告訴前端的信息,如“城市編號不存在”之類的。
package leix.lebean.sweb.common.core;
/**
* Name:RESTException
* Description: 異常信息
* Author:leix
* Time: 2017/6/20 13:58
*/
public class RESTException extends Exception {
int code;//狀態代碼
String message;//異常提示信息
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
第2步,建一個異常拼接器
創建一個異常處理器,它有兩個異常處理方法,一個處理主動拋出的異常,一個處理非主動異常。
package leix.lebean.sweb.common.config;
import leix.lebean.sweb.common.core.RESTException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
/**
* Name:ExtExceptionHandler
* Description:
* Author:leix
* Time: 2017/6/20 14:00
*/
@ControllerAdvice
public class ExtExceptionHandler {
Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* 處理業務發現問題主動拋出的異常
* @param request
* @param e
* @return
* @throws Exception
*/
@ExceptionHandler(value = RESTException.class)
@ResponseBody
public ResponseEntity<RESTException> baseErrorHandler(HttpServletRequest request, RESTException e) throws Exception {
//把錯誤輸出到日志
logger.error("RESTfulException Handler---Host: {} invokes url: {} ERROR: {}", request.getRemoteHost(), request.getRequestURL(), e.getMessage());
return new ResponseEntity<RESTException>(e, HttpStatus.valueOf(e.getCode()));
}
/**
* 系統拋出的沒有處理過的異常
* @param request
* @param e
* @return
* @throws Exception
*/
@ExceptionHandler(value = Exception.class)
@ResponseBody
public ResponseEntity<Exception> defaultErrorHandler(HttpServletRequest request, Exception e) throws Exception {
//把錯誤輸出到日志
logger.error("DefaultException Handler---Host: {} invokes url: {} ERROR: {}", request.getRemoteHost(), request.getRequestURL(), e.getMessage());
return new ResponseEntity<Exception>(new Exception("Soory, 服務器好像抽風了, 程序員小伙伴正在瘋狂搶救!"), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
? 主異常處理方法將傳遞業務處理中的異常提示信息給前端,非主動異常處理方法將統一返回一種異常提示信息到前端。
第3步,在業務中拋出異常
thow new RESTException(HttpStatus.INTERNAL_SERVER_ERROR.value(),"城市編號不存在");
詳細代碼來看這里看這里吧!源碼@github