溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Javaweb項(xiàng)目中session出現(xiàn)超時(shí)如何解決

發(fā)布時(shí)間:2020-12-05 17:34:03 來源:億速云 閱讀:350 作者:Leah 欄目:編程語言

Javaweb項(xiàng)目中session出現(xiàn)超時(shí)如何解決?很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

在Java Web開發(fā)中,Session為我們提供了很多方便,Session是由瀏覽器和服務(wù)器之間維護(hù)的。Session超時(shí)理解為:瀏覽器和服務(wù)器之間創(chuàng)建了一個(gè)Session,由于客戶端長(zhǎng)時(shí)間(休眠時(shí)間)沒有與服務(wù)器交互,服務(wù)器將此Session銷毀,客戶端再一次與服務(wù)器交互時(shí)之前的Session就不存在了。

0.需求

需要對(duì)所有的/web/**請(qǐng)求進(jìn)行登錄攔截,Session超時(shí)時(shí)跳轉(zhuǎn)到登錄頁面。

1.引入

一般來說,在項(xiàng)目使用中都會(huì)配置Session超時(shí)時(shí)間,如果不配置,則默認(rèn)值為30分鐘,即用戶不操作30分鐘以后,Session就會(huì)失效,此時(shí)用戶就需要重新登錄系統(tǒng)。

Session超時(shí)時(shí)間的配置主要的項(xiàng)目的web.xml中進(jìn)行配置,如下:

<span > <!-- 設(shè)置Session超時(shí)時(shí)間 -->  
    <session-config> 
        <!-- 分鐘 --> 
            <session-timeout>60</session-timeout> 
            <!-- 去除URL上顯示的jsessionid, 防止打開Tab頁時(shí)出現(xiàn)JS錯(cuò)誤 --> 
            <tracking-mode>COOKIE</tracking-mode> 
    </session-config></span><span > 
</span> 

2.請(qǐng)求的分類

現(xiàn)在的項(xiàng)目中請(qǐng)求主要分為兩種:一種是普通請(qǐng)求,即發(fā)起請(qǐng)求返回視圖和模型;另外一種是Ajax請(qǐng)求,主要返回模型數(shù)據(jù)。后端進(jìn)行處理時(shí)就要根據(jù)不同的請(qǐng)求返回不同的內(nèi)容。

對(duì)于普通請(qǐng)求,我們直接返回JavaScript腳本,腳本內(nèi)容可以是將頁面跳轉(zhuǎn)到登錄頁面。

對(duì)于Ajax請(qǐng)求,則需要返回非200的狀態(tài)碼,這樣ajax請(qǐng)求才會(huì)進(jìn)入到error回調(diào)函數(shù)中以及全局的Ajax錯(cuò)誤回調(diào)函數(shù)AjaxError中。

3.后端處理Session超時(shí)

后端采用SpringMVC的攔截器處理,這里為什么用攔截器呢?一方面,請(qǐng)求URL不能限制的太死,比如/*,這樣對(duì)所有的請(qǐng)求都進(jìn)行過濾是浪費(fèi)資源的。另一方面,有些URL不需要進(jìn)行攔截處理,比如到登錄頁面的請(qǐng)求肯定是不能攔截,要不然會(huì)循環(huán)重定向。再一方面,我們只需要攔截控制器請(qǐng)求,其它請(qǐng)求不攔截。

下面看一下攔截器的實(shí)現(xiàn):

/** 
* Web端登錄攔截器
* 處理請(qǐng)求時(shí)Session失效的問題,包含Ajax請(qǐng)求和普通請(qǐng)求
* @ClassName WebLoginInterceptor
* @author zhangshun
* @date 2016年10月20日 上午11:14:52
*/
public class WebLoginInterceptor extends HandlerInterceptorAdapter{
    /**
     * 日志對(duì)象
     */
    private Logger logger = LoggerFactory.getLogger(WebLoginInterceptor.class);
    /**
     * 默認(rèn)注銷URL
     * 即Session超時(shí)后,發(fā)起請(qǐng)求到此地址,只對(duì)普通請(qǐng)求有效
     */
    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請(qǐng)求, 前段根據(jù)此header進(jìn)行處理
                        response.setHeader("sessionTimeout", "Session time out, you need relogin !");
                        // 返回未認(rèn)證的狀態(tài)碼(401)
                        response.setStatus(HttpStatus.UNAUTHORIZED.value());
                            logger.debug("請(qǐng)求路徑:" + uri + ", 請(qǐng)求方式 :Ajax請(qǐng)求, Session超時(shí), 需要重新登錄!");
                        }else{
                            // 普通請(qǐng)求
                            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("請(qǐng)求路徑:" + uri + ",請(qǐng)求方式 :普通請(qǐng)求, Session超時(shí), 需要重新登錄!");
                        }
                    return false;
                }
                return true;
    }
    public String getLogoutUrl() {
        // 使用默認(rèn)值
        if(StringUtils.isEmpty(logoutUrl)){
            return DEFAULT_LOGOUT_URL;
        }
        return logoutUrl;
    }
    public void setLogoutUrl(String logoutUrl) {
        this
}

通過獲取Session中的User對(duì)象是否存在來判斷Session是否超時(shí),如果Session超時(shí),則根據(jù)不同的請(qǐng)求方式進(jìn)行返回。如果是普通請(qǐng)求,則直接返回JavaScript腳本,該腳本可以將頁面跳轉(zhuǎn)到其它URL。如果是Ajax請(qǐng)求,則返回401狀態(tài)碼,并且在返回的header中加入sessionTimeout,該數(shù)據(jù)將會(huì)在前端使用。

該攔截器在SpringMVC配置文件中的配置如下:

<span ><!-- MVC攔截器 -->
<mvc:interceptors>
    <!-- Web登錄攔截器 -->
    <mvc:interceptor>
        <mvc:mapping path="/web/**"/>
        <mvc:exclude-mapping path="/web/index"/><!-- 防止循環(huán)重定向到首頁 -->
        <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超時(shí)

對(duì)于普通請(qǐng)求,后端返回的是JavaScript腳本,會(huì)立刻執(zhí)行,這里前端不需要任何處理。

對(duì)于Ajax請(qǐng)求,后端返回401狀態(tài)碼,并在header中設(shè)置的sessionTimeout。這里使用jQuery的ajaxComplete回調(diào)函數(shù)處理,具體如下:

// 實(shí)現(xiàn)ajax請(qǐng)求時(shí)判斷Session是否失效 
$(document).ajaxComplete(function(event, response, settings) { 
 var sessionTimeout = response.getResponseHeader("SessionTimeout"); 
 if(sessionTimeout != null && typeof sessionTimeout != "undefined" && sessionTimeout.length > 0){ 
  // 這里寫Session超時(shí)后的處理方法 
 } 
}); 

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI