配置 /*、*.jsp、*.html 多重映射的登錄攔截器,訪問 localhost:8080 進入 Filter 後陷入死循環,瀏覽器報 "too many redirects"。
/* 攔截所有請求,包括登錄頁 main_login、靜態資源、重定向目標本身。sendRedirect(urlPath + loginPage) 構造的 URL 仍匹配 /*,再次進入 Filter,因 Session/Redis 無標記,再次重定向 → 死循環。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");
}
}
<filter-mapping>
<filter-name>loginInterceptor</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
移除冗餘的 *.jsp、*.html 映射,/* 已涵蓋;添加 dispatcher 避免轉發重複攔截。
已配置 <mvc:resources>,但 Filter 在 Servlet 之前執行,需在 Filter 層面同步放行,或將 Filter 映射縮小至 /app/* 等業務路徑。
doFilter 入口打印 uri、token,觀察循環路徑。