您好,登錄后才能下訂單哦!
Javaweb項目中session出現超時如何解決?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
在Java Web開發中,Session為我們提供了很多方便,Session是由瀏覽器和服務器之間維護的。Session超時理解為:瀏覽器和服務器之間創建了一個Session,由于客戶端長時間(休眠時間)沒有與服務器交互,服務器將此Session銷毀,客戶端再一次與服務器交互時之前的Session就不存在了。
0.需求
需要對所有的/web/**請求進行登錄攔截,Session超時時跳轉到登錄頁面。
1.引入
一般來說,在項目使用中都會配置Session超時時間,如果不配置,則默認值為30分鐘,即用戶不操作30分鐘以后,Session就會失效,此時用戶就需要重新登錄系統。
Session超時時間的配置主要的項目的web.xml中進行配置,如下:
<span > <!-- 設置Session超時時間 -->
<session-config>
<!-- 分鐘 -->
<session-timeout>60</session-timeout>
<!-- 去除URL上顯示的jsessionid, 防止打開Tab頁時出現JS錯誤 -->
<tracking-mode>COOKIE</tracking-mode>
</session-config></span><span >
</span>
2.請求的分類
現在的項目中請求主要分為兩種:一種是普通請求,即發起請求返回視圖和模型;另外一種是Ajax請求,主要返回模型數據。后端進行處理時就要根據不同的請求返回不同的內容。
對于普通請求,我們直接返回JavaScript腳本,腳本內容可以是將頁面跳轉到登錄頁面。
對于Ajax請求,則需要返回非200的狀態碼,這樣ajax請求才會進入到error回調函數中以及全局的Ajax錯誤回調函數AjaxError中。
3.后端處理Session超時
后端采用SpringMVC的攔截器處理,這里為什么用攔截器呢?一方面,請求URL不能限制的太死,比如/*,這樣對所有的請求都進行過濾是浪費資源的。另一方面,有些URL不需要進行攔截處理,比如到登錄頁面的請求肯定是不能攔截,要不然會循環重定向。再一方面,我們只需要攔截控制器請求,其它請求不攔截。
下面看一下攔截器的實現:
/**
* Web端登錄攔截器
* 處理請求時Session失效的問題,包含Ajax請求和普通請求
* @ClassName WebLoginInterceptor
* @author zhangshun
* @date 2016年10月20日 上午11:14:52
*/
public class WebLoginInterceptor extends HandlerInterceptorAdapter{
/**
* 日志對象
*/
private Logger logger = LoggerFactory.getLogger(WebLoginInterceptor.class);
/**
* 默認注銷URL
* 即Session超時后,發起請求到此地址,只對普通請求有效
*/
private static final String DEFAULT_LOGOUT_URL = "/web/logout";
/**
* 注銷URL
*/
private String logoutUrl;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
User user = SessionUtils.getUserFromRequestAcrossCas(request);
String uri = request.getRequestURI();
if(user == null){
response.setContentType("text/html;charset=UTF-8");
if(request.getHeader("x-requested-with") != null
&& request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")){
// Ajax請求, 前段根據此header進行處理
response.setHeader("sessionTimeout", "Session time out, you need relogin !");
// 返回未認證的狀態碼(401)
response.setStatus(HttpStatus.UNAUTHORIZED.value());
logger.debug("請求路徑:" + uri + ", 請求方式 :Ajax請求, Session超時, 需要重新登錄!");
}else{
// 普通請求
String path = request.getContextPath();
StringBuffer basePath = new StringBuffer()
.append(request.getScheme())
.append("://")
.append(request.getServerName())
.append(":")
.append(request.getServerPort())
.append(path)
.append("/");
StringBuffer responseStr = new StringBuffer()
.append("<html><header><script type=\"text/javascript\">")
.append("window.location.href=\"")
.append(basePath).append(getLogoutUrl()).append("\";")
.append("</script></header></html>");
response.getWriter().write(responseStr.toString());
logger.debug("請求路徑:" + uri + ",請求方式 :普通請求, Session超時, 需要重新登錄!");
}
return false;
}
return true;
}
public String getLogoutUrl() {
// 使用默認值
if(StringUtils.isEmpty(logoutUrl)){
return DEFAULT_LOGOUT_URL;
}
return logoutUrl;
}
public void setLogoutUrl(String logoutUrl) {
this
}
通過獲取Session中的User對象是否存在來判斷Session是否超時,如果Session超時,則根據不同的請求方式進行返回。如果是普通請求,則直接返回JavaScript腳本,該腳本可以將頁面跳轉到其它URL。如果是Ajax請求,則返回401狀態碼,并且在返回的header中加入sessionTimeout,該數據將會在前端使用。
該攔截器在SpringMVC配置文件中的配置如下:
<span ><!-- MVC攔截器 --> <mvc:interceptors> <!-- Web登錄攔截器 --> <mvc:interceptor> <mvc:mapping path="/web/**"/> <mvc:exclude-mapping path="/web/index"/><!-- 防止循環重定向到首頁 --> <mvc:exclude-mapping path="/web/login"/> <mvc:exclude-mapping path="/web/logout"/> <mvc:exclude-mapping path="/web/doLogin"/> <bean class="com.woyi.mhub.interceptor.WebLoginInterceptor"/> </mvc:interceptor> </mvc:interceptors></span><span > </span>
4.前端處理Session超時
對于普通請求,后端返回的是JavaScript腳本,會立刻執行,這里前端不需要任何處理。
對于Ajax請求,后端返回401狀態碼,并在header中設置的sessionTimeout。這里使用jQuery的ajaxComplete回調函數處理,具體如下:
// 實現ajax請求時判斷Session是否失效 $(document).ajaxComplete(function(event, response, settings) { var sessionTimeout = response.getResponseHeader("SessionTimeout"); if(sessionTimeout != null && typeof sessionTimeout != "undefined" && sessionTimeout.length > 0){ // 這里寫Session超時后的處理方法 } });
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。