关于shiroFilter的全局异常统一处理解决方案
背景
程序走到控制器时可以使用 SpringMVC 的 @ControllerAdvice 来统一处理,但是有些一访问是只是走到了拦截器那里还没有到控制器,这时候怎么进行异常统一处理呢?
解决方案
在自定义的Filter里,在需要的位置,进行请求转发,或重定向都可以,转发到控制层,当然你需要在控制层新建一个控制器来接收它,在控制器的方法里,再进行异常抛出!抛出的异常会被全局异常监测到!
上代码
自定义的token验证拦截器
@Override
protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
log.info("MJwtFilter-认证token!");
HttpServletRequest request = WebUtils.toHttp(servletRequest);
HttpServletResponse response = WebUtils.toHttp(servletResponse);
//得到token
Enumeration<String> a = WebUtils.toHttp(request).getHeaders("Access-Control-Request-Headers");
String token = WebUtils.toHttp(request).getHeader("token");
//验证token
if (token == null) {
//过滤器处理异常,用请求转发来处理或重定向
request.setAttribute("exception", "未携带令牌");
request.getRequestDispatcher("/base/nullToken").forward(request, response);
return false;
}
try {
Map<String, Claim> claimMap1 = JwtTokenUtils.verifyToken(token);
String username = claimMap1.get("username").asString();
long userId = claimMap1.get("userId").asLong();
Map<String, Object> map = new HashMap<>();
map.put("username", username);
map.put("userId", userId);
//绑定当前用户对象到shiro环境
ShiroUtils.bindPrincipal(map, request, response);
} catch (TokenExpiredException e) {
String redirectUrl = request.getContextPath() + "/base/overdue";
response.sendRedirect(redirectUrl);
return false;
}
return true;
}
统一处理异常的控制器
@Controller
@RequestMapping("base")
public class ExceptionController {
//没有携带令牌
@RequestMapping("nullToken")
public String nullToken(HttpServletRequest request) throws Exception {
throw new UnsupportedTokenException((String) request.getAttribute("exception"));
}
//令牌过期
@RequestMapping("overdue")
public String overdue(HttpServletRequest request) throws Exception {
throw new TokenExpiredException((String) request.getAttribute("exception"));
}
}
::: tip
编程是一种思想
:::
本作品采用《CC 协议》,转载必须注明作者和本文链接