關於shiroFilter的全域性異常統一處理解決方案

juan發表於2021-02-04

背景

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

相關文章