天天看點

SpringMVC 攔截器遇到浏覽器請求/favicon.ico被攔截導緻觸發session失效問題的處理辦法

現狀做的一個練手項目,根據慕課網的仿大衆點評源碼自己修改的,使用session攔截器+auth攔截器。

之前用的Chrome浏覽器,遇到的問題:登入背景,加載完菜單後,點進每一個子菜單都被踢回到login,打斷點總是發現session被莫名其妙的清掉,期初以為是session攔截器出了問題,但源碼基本沒動呀,該不會有坑?

/**
 * session攔截器
 */
public class SessionInterceptor implements HandlerInterceptor {

	/**
	 * 在進入Handler方法執行之前執行本方法
	 * 
	 * @return true:執行下一個攔截器,直到所有攔截器都執行完,再執行被攔截的Controller
	 *         false:從目前的攔截器往回執行所有攔截器的afterCompletion(),再退出攔截器鍊
	 */
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		//這裡的使用者資訊在加載完菜單後就變成了null
		System.out.println(request.getSession().getAttribute(SessionKeyConst.USER_INFO));
		if (request.getSession().getAttribute(SessionKeyConst.USER_INFO) != null) {
			return true;
		}
		// 針對ajax請求處理
		if (request.getHeader("x-requested-with") != null) {
			String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
			response.setHeader("url", basePath + "/login/sessionTimeout");
		} else {
			request.getRequestDispatcher("/login/sessionTimeout").forward(request, response);
		}
		return false;
	}
}
           

後來觀察AuthInterceptor的uri,發現下面代碼的情況(/login/sessionTimeout和下面的/login/noAuth方法都是觸發的session.invalidate())

public class AuthInterceptor implements HandlerInterceptor {

	/**
	 * 在進入Handler方法執行之前執行本方法
	 * 
	 * @return true:執行下一個攔截器,直到所有攔截器都執行完,再執行被攔截的Controller
	 *         false:從目前的攔截器往回執行所有攔截器的afterCompletion(),再退出攔截器鍊
	 */
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		//這裡的request.getServletPath()出現了/favicon.ico的請求
		if (CommonUtil.contains(request.getSession(), request.getServletPath(), request.getMethod())) {
			return true;
		}
		// 針對ajax請求處理
		if (request.getHeader("x-requested-with") != null) {
			String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
			response.setHeader("url", basePath + "/login/noAuth");
		} else {
			request.getRequestDispatcher("/login/noAuth").forward(request, response);
		}
		return false;
	}
}
           

這個/favicon.ico請求從哪來的?我搜了整個項目都沒找到favicon.ico的字眼,我的項目裡也沒有favicon.ico這個檔案,後來通過Google,發現浏覽器自己會在頁面加載完成後發起一個/favicon.ico的請求,這就有點蛋疼了,你請求都不告訴我一聲,結果被我的auth攔截器攔下造成我session莫名其妙的被清空,害的我還找了半天原因。

解決辦法:攔截器直接放行就ok啦~

<!-- 過濾浏覽器發起的/favicon.ico請求,防止session被清空 -->
 <mvc:exclude-mapping path="/favicon.ico"/>
           

再從需要的頁面裡引用上 icon

<link rel="shortcut icon" href="/favicon.ico" target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow" />
<link rel="bookmark" href="/favicon.ico" target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow" />
           

就ok了

SpringMVC 攔截器遇到浏覽器請求/favicon.ico被攔截導緻觸發session失效問題的處理辦法