1.项目中异常处理挺常见的,有时候系统内部出现异常,返回给外部系统异常,或者想获得自己想要的异常,就需要自己处理了,话不多说开整。
2.原理:RestControllerAdvice 对Controller进行增强的,可以全局捕获spring mvc抛的异常。
3.首先需要写一个异常处理器用来处理自己的异常,再写一个自定义的异常类,最后通过代码进行测试即可。
a.自定义异常处理类
package com.example.demo.exception;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.enetity.ResponseBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
@ResponseBody
public class GlobalExcetionHandler {
private static final Logger logger= LoggerFactory.getLogger(GlobalExcetionHandler.class);
//自定义的异常处理器
@ExceptionHandler(CommonJsonException.class)
public ResponseBean CommonJsonExceptionHander(CommonJsonException commonJsonException){
logger.info("自定义异常");
return commonJsonException.getResponseBean();
}
//默认的处理器
@ExceptionHandler(Exception.class)
public ResponseBean defaultExceptionHander(Exception e){
logger.info("常规异常");
ResponseBean responseBean = new ResponseBean();
responseBean.setResult(new JSONObject());
responseBean.setRetCode("1");
responseBean.setRetMsg("系统异常");
return responseBean ;
}
}
2.异常类的编写需要继承runntimeException
package com.example.demo.exception;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.enetity.ResponseBean;
import com.example.demo.util.ErrorEnum;
public class CommonJsonException extends RuntimeException {
private ResponseBean responseBean;
public CommonJsonException(ErrorEnum errorEnum){
responseBean= new ResponseBean(errorEnum);
}
public CommonJsonException(String retCode,String retMsg){
responseBean= new ResponseBean(retCode,retMsg);
responseBean.setResult(new JSONObject());
}
public ResponseBean getResponseBean(){
return responseBean;
}
}
返回的格式
1.枚举类
package com.example.demo.util;
public enum ErrorEnum {
//错误
E_1001("1001","错误"),
//参数缺失
E_1002("1002","参数缺失"),
//用户不存在
E_1003("1003","用户不存在"),
//密码错误
E_1004("1004","密码错误"),
//核心系统请求异常
E_1005("1005","核心系统请求异常");
private String errorCode;
public String getErrorCode() {
return errorCode;
}
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
private String errorMsg;
ErrorEnum(String errorCode, String errorMsg) {
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
}
2.返回结果类
package com.example.demo.enetity;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.util.ErrorEnum;
public class ResponseBean {
private String retCode;
private String retMsg;
private JSONObject result;
public ResponseBean(){
}
public ResponseBean(String retCode, String retMsg, JSONObject result) {
this.retCode = retCode;
this.retMsg = retMsg;
this.result = result;
}
public ResponseBean(String retCode, String retMsg) {
this.retCode = retCode;
this.retMsg = retMsg;
}
public ResponseBean(ErrorEnum errorEnum) {
this.retCode = errorEnum.getErrorCode();
this.retMsg = errorEnum.getErrorMsg();
this.result = new JSONObject();
}
public String getRetCode() {
return retCode;
}
public String getRetMsg() {
return retMsg;
}
public void setRetMsg(String retMsg) {
this.retMsg = retMsg;
}
public JSONObject getResult() {
return result;
}
public void setResult(JSONObject result) {
this.result = result;
}
public void setRetCode(String retCode) {
this.retCode = retCode;
}
}
好了到此为止,异常类和对应处理器就写好了,然后再写个方法即可。
@GetMapping("/test/exception")
public ResponseBean testException() throws Exception {
throw new RuntimeException();
}
@GetMapping("/test/commonJsonException")
public ResponseBean testCommonJsonException() throws Exception {
throw new CommonJsonException("1","2");
}
请求两个地址的到结果
好了到此为止就好了。
扩展
其实异常的逻辑是从小到大的来处理,如果A异常继承B异常,B异常继承C异常,那么
抛出一个A异常,异常处理器会先看有没有A专属的处理,有就执行,没有给B专属的执行,再没有给C的专属执行,最终都交给Exception来处理,这就是默认的接盘侠了。
测试
处理器
package com.example.demo.exception;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.enetity.ResponseBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
@ResponseBody
public class GlobalExcetionHandler {
private static final Logger logger= LoggerFactory.getLogger(GlobalExcetionHandler.class);
@ExceptionHandler(CommonJsonException.class)
public ResponseBean CommonJsonExceptionHander(CommonJsonException commonJsonException){
logger.info("自定义异常");
return commonJsonException.getResponseBean();
}
@ExceptionHandler(CommonJsonChildException.class)
public ResponseBean CommonJsonChildException(CommonJsonException commonJsonException){
logger.info("自定义儿子异常");
return commonJsonException.getResponseBean();
}
@ExceptionHandler(CommonJsonChildMoreException.class)
public ResponseBean CommonJsonChildMoreException(CommonJsonException commonJsonException){
logger.info("自定义孙子异常");
return commonJsonException.getResponseBean();
}
@ExceptionHandler(Exception.class)
public ResponseBean defaultExceptionHander(Exception e){
logger.info("常规异常");
ResponseBean responseBean = new ResponseBean();
responseBean.setResult(new JSONObject());
responseBean.setRetCode("1");
responseBean.setRetMsg("系统异常");
return responseBean ;
}
}
测试类
@GetMapping("/test/exception")
public ResponseBean testException() throws Exception {
throw new CommonJsonChildException("1","2");
}
@GetMapping("/test/commonJsonException")
public ResponseBean testCommonJsonException() throws Exception {
throw new CommonJsonChildMoreException("1","2");
}
执行效果
然后将孙子异常处理注释
package com.example.demo.exception;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.enetity.ResponseBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
@ResponseBody
public class GlobalExcetionHandler {
private static final Logger logger= LoggerFactory.getLogger(GlobalExcetionHandler.class);
@ExceptionHandler(CommonJsonException.class)
public ResponseBean CommonJsonExceptionHander(CommonJsonException commonJsonException){
logger.info("自定义异常");
return commonJsonException.getResponseBean();
}
@ExceptionHandler(CommonJsonChildException.class)
public ResponseBean CommonJsonChildException(CommonJsonException commonJsonException){
logger.info("自定义儿子异常");
return commonJsonException.getResponseBean();
}
// @ExceptionHandler(CommonJsonChildMoreException.class)
// public ResponseBean CommonJsonChildMoreException(CommonJsonException commonJsonException){
// logger.info("自定义孙子异常");
// return commonJsonException.getResponseBean();
// }
@ExceptionHandler(Exception.class)
public ResponseBean defaultExceptionHander(Exception e){
logger.info("常规异常");
ResponseBean responseBean = new ResponseBean();
responseBean.setResult(new JSONObject());
responseBean.setRetCode("1");
responseBean.setRetMsg("系统异常");
return responseBean ;
}
}
执行结果
都子类的异常没有处理的,让父类处理解决了,一层一层往上抛出,最终到达Exception,所以在项目中可以写一个以exception为基准的处理类,用来接盘所有的异常返回统一的一个结果即可。