在项目中,我们的Dao层处理数据可能会出问题,Service层可能会遇到NPE等问题,Controller层会遇到参数处理问题等等。一般情况下我们不会直接把异常丢给客户端,需要对错误进行包装。
其实SpringBoo有默认的异常处理,但是在我看来SpringBoot默认处理异常只是用来学习时候来定义问题,在业务开发中我们还是需要自定义自己的业务异常处理。
1. 新建统一异常处理类
@ControllerAdvice 定义统一异常处理类。所有经过Controller的异常都可以处理。
@ExceptionHandler 定义处理声明特定的异常。一次可以声明多个异常。
@ControllerAdvice
public class GlobalExceptionHandler {
private static Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler(value={BussinessException.class})
@ResponseBody
public ResultModel jsonHandler(HttpServletRequest request,Exception e) throws IOException{
BussinessException bussinessException = (BussinessException) e;
logger.error("请求路径:{}",request.getRequestURI());
logger.error("请求方法:{}",request.getMethod());
if (request.getMethod().equals(RequestMethod.GET)) {
logger.error("请求参数:{}",request.getQueryString());
}else if (request.getMethod().equals(RequestMethod.POST)) {
logger.error("请求参数:{}",request.getReader().toString());
}
logger.error("异常原因:{}",e);
ResultModel rm = new ResultModel<>();
rm.setCode(bussinessException.getCode());
rm.setMsg(bussinessException.getMessage());
return rm;
}
}
我们定义一个全局异常处理器,现在处理BussinessException(我们自己自定义的业务异常对象)。返回一个对象。
2. 自定义业务异常
我们业务异常继承RuntimeException,并增加错误码。
其实业务开发中可以继续丰富我们异常的一些参数和内容。
public class BussinessException extends RuntimeException{
// 错误码
private String code;
public BussinessException(String code,String msg){
super(msg);
this.setCode(code);
}
}
3. 请求测试
定义两个请求方法。
第一个不处理使用spring boot默认异常返回。
第二个抛出我们自定义异常。
@RequestMapping("demo")
public int demo(Integer a,Integer b){
return a/b;
}
@RequestMapping("demo2")
public int demo2(Integer a,Integer b){
if (b==0) {
throw new BussinessException("2001", "参数不能是0或空");
}
return a/b;
}
请求http://localhost:8080/exception/demo1?a=2&b=0
{
"timestamp": 1554021093124,
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/exception/demo1"
}
请求http://localhost:8080/exception/demo2?a=2&b=0
{
"code": "2001",
"msg": "参数不能是0或空",
"data": null
}
根据结果我们可以看到返回结果是我们自定义异常返回的数据。
源码下载 :Github
网友评论