版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/liuchuanhong1/article/details/76974908
在前面的博客中,Spring Boot整合jpa,Shiro进行权限管理 异常都是直接返回到页面上,这样做既不安全,也不友好,所以在返回给页面之前,我们需要对异常信息进行统一的处理,该部分的处理思路和spring mvc的处理思路是一致的。
下面,我们来对前面的示例进行改造,从而能够支持统一的异常处理。
1、定义全局异常处理类
@ControllerAdvice
public class GlobalExceptionHandler {// 此处仅用作测试
@ExceptionHandler(value = Exception.class)
public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
ModelAndView mav = new ModelAndView();
if (e instanceof UnauthorizedException) {// 判断异常类型
mav.addObject("exception", "无权访问!");// 根据异常类型,返回具体的展示信息
} else {
mav.addObject("exception", "系统错误,请联系管理员@chhliu!");
}
mav.addObject("url", req.getRequestURL());
mav.setViewName("/error");// 异常信息展示到哪个页面,此处指定在error.html页面中进行展示
return mav;
}
}
从上面的示例可以得出,我们可以通过@ControllerAdvice来定义统一的异常处理类,使用@ExceptionHandler来决定哪些异常需要处理,当然,我们也可以在程序中针对具体的异常类进行判断。
2、映射异常处理页面
默认的情况下,所有的异常信息都会映射到error页面,所以,我们需要在templates目录下新建一个error.html的异常展示页面,如下:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8" />
<title>统一异常处理</title>
</head>
<body>
<h1>Error Handler, 无权限访问</h1>
</body>
</html>
3、在Controller中抛出异常
一般情况下,我们的异常处理都是从底层往上层抛,比如Dao层往Service层抛,Service层往Controller层抛,当Controller层还往外层抛的时候,就会被我们的全局异常处理器捕获了。
通过上面的几个步骤,就完成了异常的统一处理了,但是在我们的实际开发中,我们的异常信息通常是以json格式返回给服务调用端的,那怎么来统一处理返回json格式的字符串了?处理起来也很简单,我们在上面的代码中做下修改即可。
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = Exception.class)
@ResponseBody// 返回json数据
public ErrorInfo<String> jsonErrorHandler(HttpServletRequest req, Exception e) throws Exception {
ErrorInfo<String> r = new ErrorInfo<>();// 异常信息封装类
r.setMessage(e.getMessage());
r.setCode("403");
r.setData("无权访问");
r.setUrl(req.getRequestURL().toString());
return r;
}
}
测试结果如下:
{"code":"403","message":"Subject does not have permission [userInfo:del]","url":"http://172.28.1.1:8080/userInfo/userDel","data":"无权访问"}
这样,我们就完成了统一异常的处理了。这样,既保证了异常信息不泄露,同时前端的展示也非常友好。