異常定義
**1. 通用異常:**就是系統産生的異常
(1)狀态碼
(2)提示資訊
/***
* 通用異常定義
*/
public enum CommonException {
SYSTEM_EXCEPTION(-1,"系統繁忙,請稍後重試");
private Integer code;
private String message;
CommonException(Integer code, String message) {
this.code = code;
this.message = message;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
**2.業務異常:**如使用者登入失敗等
(1) 狀态碼
(2) 提示資訊
/***
* 使用者業務異常
*/
public enum UserException {
USER_PASSWORD_ERROR(1001,"使用者名或密碼錯誤");
private Integer code;
private String message;
UserException(Integer code, String message) {
this.code = code;
this.message = message;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
業務中調用
此處的ReturnResultUtils.returnFail方法是我自己定義的一個傳回值的方法,可以檢視[統一傳回資料](https://blog.csdn.net/qq_40664795/article/details/105570986)
ReturnResultUtils.returnFail(CommonException.SYSTEM_EXCEPTION.getCode(),Com
monException.SYSTEM_EXCEPTION.getMessage());
統一異常處理
實作步驟
① 編寫攔截器,攔截抛出的異常
/***
* 異常統一處理的攔截器
*/
public class ExceptionInterceptor implements HandlerInterceptor{
/**
* 方法處理前
* @param httpServletRequest
* @param httpServletResponse
* @param o
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");//這一步主要是前後端分離統一在方法處理前進行攔截解決跨域問題
return true;//true開啟攔截功能
}
/**
* 方法處理後,傳回前
*/
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
/***
* 方法處理完成後
* @param request
* @param response
* @param o
* @param e
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) throws Exception {
//出現異常進行處理
if(EmptyUtils.isNotEmpty(e)){
response.setContentType("text/html;charset=UTF-8");//設定傳回值的編碼格式
PrintUtil printUtil=new PrintUtil(response); //自己封裝的一個輸出流工具,由于該方法是void,是以不能把異常return回去,通過流的方式處理
ReturnResult returnResult=ReturnResultUtils.returnFail(CommonException.SYSTEM_EXCEPTION.getCode(),CommonException.SYSTEM_EXCEPTION.getMessage());//傳回異常資訊
printUtil.print(JSONObject.toJSON(returnResult));//轉成JSONObject
}
}
}
printUtil工具
import org.apache.log4j.Logger;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class PrintUtil {
//列印日志
static Logger logger=Logger.getLogger(PrintUtil.class);
public HttpServletResponse response;
public PrintUtil(HttpServletResponse response, String contentType){
this.response=response;
this.response.setContentType(contentType);
}
public PrintUtil(HttpServletResponse response){
this.response=response;
}
public void print(Object msg){
PrintWriter writer=null;
try {
if(null != response){
//如果系統打開了outputStream 那麼将其關閉
writer=new PrintWriter(response.getOutputStream());
String temp=new String(String.valueOf(msg));
writer.write(temp);
writer.flush();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
writer.close();
}
}
}
② 判斷異常,進行資料傳回
引入處理json依賴
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.54</version>
</dependency>
捕獲了異常進行處理
/***
* 方法處理完成後
* @param request
* @param response
* @param o
* @param e
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) throws Exception {
//出現異常進行處理
if(EmptyUtils.isNotEmpty(e)){
response.setContentType("text/html;charset=UTF-8");//設定傳回值的編碼格式
PrintUtil printUtil=new PrintUtil(response); //自己封裝的一個輸出流工具,由于該方法是void,是以不能把異常return回去,通過流的方式處理
ReturnResult returnResult=ReturnResultUtils.returnFail(CommonException.SYSTEM_EXCEPTION.getCode(),CommonException.SYSTEM_EXCEPTION.getMessage());//傳回異常資訊
printUtil.print(JSONObject.toJSON(returnResult));//轉成JSONObject
}
}
第3步
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/***
* 配置攔截器
*/
@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {
/**
* 把ExceptionInterceptor異常交給springIOC管理,如果定義了多個異常類,那也要像這樣添加多個
* @return
*/
@Bean
public ExceptionInterceptor exceptionInterceptor(){
return new ExceptionInterceptor();
}
/**
* 定義的登入異常資訊
* @return
*/
@Bean
public LoginInterceptor loginInterceptor(){
return new LoginInterceptor();
}
/**
* 要實作WebMvcConfigurerAdapter的addInterceptors這個方法
* 在ExceptionInterceptor異常裡凡是api/後面的都進行攔截
* 在LoginInterceptor異常裡凡是api/v/後面的都進行攔截
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(exceptionInterceptor()).addPathPatterns("/api/**");
registry.addInterceptor(loginInterceptor()).addPathPatterns("/api/v/**");
super.addInterceptors(registry);
}
}
在業務中處理異常不再需要try-cartch進行捕獲異常了,直接抛出即可(也就是有異常不處理,抛給攔截器進行統一處理),應該如果有異常會在攔截器攔截時進行攔截處理
/***
* 根據使用者名和密碼生成token
* @param phone
* @param password
* @return
*/
public ReturnResult validateToken(String phone, String password)throws Exception{
ReturnResult returnResult=null;
QgUser qgUser=null;
String token=null;
qgUser=qgUserService.queryQgUserByPhoneAndPwd(phone,password);
if(null!=qgUser){
//如果驗證成功,生成token放在redis
String oldToken=redisUtil.getStr(qgUser.getId());
if(EmptyUtils.isNotEmpty(oldToken)){
redisUtil.del(oldToken);
redisUtil.del(qgUser.getId());
}
token=Constants.tokenPrefix+TokenUtils.createToken(qgUser.getId(),qgUser.getPhone());
redisUtil.setStr(token, JSONObject.toJSONString(qgUser), Constants.loginExpire);
redisUtil.setStr(qgUser.getId(), token,Constants.loginExpire);
Map<String,Object> result=new HashMap<String,Object>();
result.put("token",token);
returnResult= ReturnResultUtils.returnSuccess(result);
}else{
returnResult= ReturnResultUtils.returnFail(UserException.USER_PASSWORD_ERROR.getCode(),UserException.USER_PASSWORD_ERROR.getMessage());
}
return returnResult;
}