首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Java Web Filter 死循環排查:URL 模式過濾與重定向邏輯錯誤

     編輯:程式設計疑難解答

問題現象

配置 /*、*.jsp、*.html 多重映射的登錄攔截器,訪問 localhost:8080 進入 Filter 後陷入死循環,瀏覽器報 "too many redirects"。

核心原因

  1. 過濾路徑過廣:/* 攔截所有請求,包括登錄頁 main_login、靜態資源、重定向目標本身。
  2. 重定向未放行:sendRedirect(urlPath + loginPage) 構造的 URL 仍匹配 /*,再次進入 Filter,因 Session/Redis 無標記,再次重定向 → 死循環。
  3. 登錄頁邏輯缺失:未在 doFilter 中排除登錄頁路徑。

修正代碼

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
        throws IOException, ServletException {
    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse resp = (HttpServletResponse) response;
    String uri = req.getRequestURI(); // 不含參數
    String ctx = req.getContextPath();

    // 1. 放行靜態資源
    if (uri.startsWith(ctx + "/css/") || 
        uri.startsWith(ctx + "/js/") || 
        uri.startsWith(ctx + "/images/")) {
        chain.doFilter(request, response);
        return;
    }

    // 2. 放行登錄頁及登錄提交接口
    if (uri.endsWith("/main_login") || uri.endsWith("/login")) {
        chain.doFilter(request, response);
        return;
    }

    // 3. 檢查登錄狀態
    String token = jedisClient.get("key1"); // 建議從 Session 獲取
    if (token != null) {
        chain.doFilter(request, response);
    } else {
        // 重定向到登錄頁(絕對路徑)
        resp.sendRedirect(ctx + "/main_login");
    }
}

web.xml 優化

<filter-mapping>
  <filter-name>loginInterceptor</filter-name>
  <url-pattern>/*</url-pattern>
  <dispatcher>REQUEST</dispatcher>
  <dispatcher>FORWARD</dispatcher>
</filter-mapping>

移除冗餘的 *.jsp、*.html 映射,/* 已涵蓋;添加 dispatcher 避免轉發重複攔截。

Spring MVC 靜態資源放行

已配置 <mvc:resources>,但 Filter 在 Servlet 之前執行,需在 Filter 層面同步放行,或將 Filter 映射縮小至 /app/* 等業務路徑。

調試技巧

  • 在 doFilter 入口打印 uri、token,觀察循環路徑。
  • 瀏覽器網絡面板查看 302 重定向鏈。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved