背景
程式走到控制器時可以使用 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 協議》,轉載必須註明作者和本文連結