完整代碼地址在結(jié)尾O舳埂奸披!
第一步,創(chuàng)建一個SpringBoot項目涮雷,此處不贅述
第二步阵面,編寫application.yml配置文件,如下
server:
port: 8085
spring:
application:
name: exception-demo-server
第三步洪鸭,創(chuàng)建響應碼枚舉ResponseEnums样刷,統(tǒng)一響應類Response,如下
ResponseEnums
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @version 1.0
* @author jinhaoxun
* @date 2018-05-09
* @description 響應碼枚舉
*/
@Getter
@AllArgsConstructor
public enum ResponseEnums {
/**
* 請求成功
*/
SUCCESS(200,"請求成功"),
/**
* 系統(tǒng)異常览爵,請稍后重試
*/
EXCEPTION(10000,"系統(tǒng)異常颂斜,請稍后重試"),
/**
* 請求的資源(網(wǎng)頁等)不存在
*/
NOT_FOUND(404,"請求的資源(網(wǎng)頁等)不存在"),
/**
* 共6位,1:系統(tǒng)異常碼和值定義在該類中,大家公用
* 前2位表示大板塊(10:系統(tǒng)拾枣,11:管理后臺模塊沃疮,12:文章模塊,13:公共模塊梅肤,14:上傳下載文件模塊)
* 第3,4位表示項目的小模塊司蔬,5,6位代表具體錯誤
*/
/************************** 系統(tǒng)模塊 *******************************/
/**
* 登陸超時
*/
LOGIN_TIMEOUT(100001 ,"登陸超時"),
/**
* 參數(shù)有誤
*/
WRONG_PARAM(100002 ,"參數(shù)有誤"),
/**
* 缺少必要的參數(shù)
*/
MISS_PARAM(100003 ,"缺少必要的參數(shù)"),
/**
* Hystrix 降級開啟拋出異常
*/
HYSTRIX_THROW_EXCEPTION(100004 ,"請求超時姨蝴,請稍后重試"),
/************************** 賬號模塊 *******************************/
/**
* 您沒有該權限
*/
MNG_PERMISSION_DENY(110101,"您沒有該權限"),
/**
* 密碼錯誤
*/
PASSWORD_WRONG(110102,"密碼錯誤"),
/**
* 用戶不存在
*/
USER_NOT_EXIST(110103,"用戶不存在"),
/**
* 賬號被封禁
*/
ACCOUNT_IS_BLOCKED(110104,"賬號被封禁"),
/**
* 賬號已注銷
*/
ACCOUNT_IS_CANCELLED(110105,"賬號已注銷"),
/**
* 驗證碼已過期
*/
VERIFICATION_CODE_EXPIRED(110106,"驗證碼已過期"),
/**
* 從Redis中獲取驗證碼錯誤
*/
GET_CODE_WRONG_FROM_REDIS(110107,"從Redis中獲取驗證碼錯誤"),
/**
* 身份信息已過期
*/
IDENTITY_INFORMATION_IS_EXPIRED(110108,"身份信息已過期"),
/**
* 用戶未登錄
*/
USER_NOT_LOG_IN(110109,"用戶未登錄"),
/**
* 用戶退出登錄失敗
*/
USER_LOG_OUT_FAIL(110110,"用戶退出登錄失敗"),
/**
* 密碼修改失敗
*/
PASSWORD_CHANGE_FAIL(110112,"密碼修改失敗"),
/**
* 賬號封禁失敗
*/
ACCOUNT_BLOCK_FAIL(110113,"賬號封禁失敗"),
/**
* 賬號解封失敗
*/
ACCOUNT_UNSEALING_FAIL(110114,"賬號解封失敗"),
/**
* 賬號注冊失敗
*/
ACCOUNT_REGISTRATION_FAIL(110115,"賬號注冊失敗"),
/**
* 獲取手機驗證碼失敗
*/
GET_PHONE_CODE_FAIL(110116,"獲取手機驗證碼失敗"),
/**
* 獲取郵箱驗證碼失敗
*/
GET_EMAIL_CODE_FAIL(110117,"獲取郵箱驗證碼失敗"),
/**
* 獲取用戶信息失敗
*/
GET_USERINFO_FAIL(110118,"獲取用戶信息失敗"),
/**
* 更新用戶信息失敗
*/
UPDATE_USERINFO_FAIL(110119,"更新用戶信息失敗"),
/**
* 賬號注銷失敗
*/
ACCOUNT_CANAEL_FAIL(110120,"賬號注銷失敗"),
/**
* 重復獲取驗證碼
*/
REPEAT_GET_USER_LOG_IN_CODE(110121,"重復獲取驗證碼"),
/**
* 驗證碼已過期
*/
USER_LOG_IN_CODE_EXPIRATIONED(110122,"驗證碼已過期"),
/**
* 驗證碼錯誤
*/
USER_LOG_IN_CODE_WRONG(110123,"驗證碼錯誤"),
;
public Integer code;
public String msg;
}
Response
import com.luoyu.exception.constant.ResponseEnums;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
* Response
*
* @author luoyu
* @date 2018/10/07 13:28
* @description 通用返回類
*/
@Data
public class Response implements Serializable {
private String msg;
private int code;
private Object data;
private String time;
private Response() {
}
private Response(int code, String msg) {
this.code = code;
this.msg = msg;
this.time = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now());
}
private Response(int code, String msg, Object data) {
this.code = code;
this.msg = msg;
this.data = data;
this.time = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now());
}
public static Response success() {
return new Response(ResponseEnums.SUCCESS.getCode(), ResponseEnums.SUCCESS.getMsg());
}
public static Response success(Object data) {
return new Response(ResponseEnums.SUCCESS.getCode(), ResponseEnums.SUCCESS.getMsg(), data);
}
public static Response success(Object data, String msg) {
return new Response(ResponseEnums.SUCCESS.getCode(), msg, data);
}
public static Response fail() {
return new Response(ResponseEnums.EXCEPTION.getCode(), ResponseEnums.EXCEPTION.getMsg());
}
public static Response fail(ResponseEnums responseEnums) {
return new Response(responseEnums.getCode(), responseEnums.getMsg());
}
public static Response fail(ResponseEnums responseEnums, Object data) {
return new Response(responseEnums.getCode(), responseEnums.getMsg(), data);
}
public static Response fail(int code, String msg) {
return new Response(code, msg);
}
public static Response fail(int code, String msg, Object data) {
return new Response(code, msg, data);
}
}
第四步俊啼,創(chuàng)建自定義異常類CustomException,如下
import lombok.Data;
import java.io.Serializable;
/**
* @version 1.0
* @author jinhaoxun
* @date 2018-05-09
* @description 自定義統(tǒng)一異常(相當于業(yè)務異常)
*/
@Data
public class CustomException extends Exception implements Serializable {
private static final long serialVersionUID = 1L;
private Integer code;
private String log;
/**
* @author jinhaoxun
* @description 構(gòu)造器
* @param code 異常狀態(tài)碼
* @param log 異常打印日志
* @param msg 異常返回信息
*/
public CustomException(Integer code, String log, String msg) {
super(msg);
this.code = code;
this.log = log;
}
}
第五步左医,創(chuàng)建全局異常統(tǒng)一處理類ExceptionHandle授帕,如下
import com.luoyu.exception.constant.ResponseEnums;
import com.luoyu.exception.entity.vo.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* @version 1.0
* @author jinhaoxun
* @date 2018-05-09
* @description 統(tǒng)一的異常處理
*/
@Slf4j
@RestControllerAdvice
public class ExceptionHandle {
/**
* @author jinhaoxun
* @description 統(tǒng)一的異常處理方法
* @param e 拋出的異常
* @return 返回給前端的錯誤信息提示
*/
@ExceptionHandler(value = Exception.class)
public Response handleException(Exception e){
if(e instanceof CustomException) {
CustomException ex = (CustomException)e;
log.info("自定義業(yè)務異常:msg:" + ex.getMessage() + ",log:" + ex.getLog(), e);
return Response.fail(ex.getCode(), ex.getMessage(),null);
}else if(e instanceof MethodArgumentNotValidException) {
MethodArgumentNotValidException ex = (MethodArgumentNotValidException)e;
log.error("參數(shù)校驗異常:msg:" + ex.getBindingResult().getFieldError().getDefaultMessage());
return Response.fail(ResponseEnums.WRONG_PARAM.getCode(),
ResponseEnums.WRONG_PARAM.getMsg() + ":"
+ ex.getBindingResult().getFieldError().getDefaultMessage(), null);
}else{
log.error("統(tǒng)一系統(tǒng)異常:msg:" + e.getMessage(), e);
return Response.fail(ResponseEnums.EXCEPTION.getCode(), ResponseEnums.EXCEPTION.getMsg(), null);
}
}
}
說明
- @ExceptionHandler用于統(tǒng)一處理某一類異常浮梢,從而能夠減少代碼重復率和復雜度跛十,所有拋出來的異常都會在這里被捕獲
第六步,創(chuàng)建TestService秕硝,TestServiceImpl芥映,TestController,如下
TestService
/**
* @Description:
* @Author: jinhaoxun
* @Date: 2020/7/10 10:31 上午
* @Version: 1.0.0
*/
public interface TestService {
void get1() throws Exception;
void get2() throws Exception;
}
TestServiceImpl
import com.luoyu.exception.exception.CustomException;
import com.luoyu.exception.service.TestService;
import org.springframework.stereotype.Service;
/**
* @Description:
* @Author: jinhaoxun
* @Date: 2020/7/10 10:32 上午
* @Version: 1.0.0
*/
@Service
public class TestServiceImpl implements TestService {
@Override
public void get1() throws Exception {
int i = 1/0;
}
@Override
public void get2() throws Exception {
try {
int i = 1/0;
}catch (Exception e){
throw new CustomException(10086, "自定義打印異常", "自定義返回異常");
}
}
}
TestController
import com.luoyu.exception.entity.vo.Response;
import com.luoyu.exception.service.TestService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* @Description:
* @Author: jinhaoxun
* @Date: 2020/7/10 10:31 上午
* @Version: 1.0.0
*/
@RestController
@RequestMapping("/test")
public class TestController {
@Resource
private TestService testService;
/**
* @author jinhaoxun
* @description 測試接口1
*/
@GetMapping("/get1")
public Response get1() throws Exception {
testService.get1();
return Response.success();
}
/**
* @author jinhaoxun
* @description 測試接口2
*/
@GetMapping("/get2")
public Response get2() throws Exception {
testService.get2();
return Response.success();
}
}
解釋
- 從可能出現(xiàn)異常的地方往外面拋異常,本文是從service開始奈偏,直到controller往外面拋出異常后坞嘀,會被ExceptionHandle捕獲,然后自行進行處理惊来,打印日志丽涩,統(tǒng)一狀態(tài)碼,錯誤信息返回給前端裁蚁。
第七步内狸,啟動項目,使用postman調(diào)接口厘擂,如下圖
注:此工程包含多個module刽严,本文所用代碼均在exception-demo模塊下