Javawebプロジェクトのセッションタイムアウトの問題を解決する

黄舟
リリース: 2017-09-21 10:16:04
オリジナル
2347 人が閲覧しました

この記事では主に Javaweb プロジェクトのセッション タイムアウト ソリューションを紹介します。ソリューションの分類は比較的明確であり、必要な場合は内容が詳しく説明されています。

Java Web 開発では、セッションはブラウザとサーバーの間で維持されるため、非常に便利です。セッション タイムアウトは次のように理解されます。 ブラウザとサーバーの間にセッションが作成され、クライアントが長時間 (スリープ時間) サーバーと対話しないため、クライアントが再度サーバーと対話すると、サーバーはこのセッションを破棄します。前のセッションは存在しません。

0. 要件

すべての /web/** リクエストのログインをインターセプトし、セッションがタイムアウトしたときにログイン ページにジャンプする必要があります。

1. はじめに

一般に、セッション タイムアウトはプロジェクトの使用中に設定されます。設定されていない場合、デフォルト値は 30 分です。つまり、ユーザーが 30 分間操作しなかった場合、セッションは終了します。これは期限切れになります。ユーザーはシステムに再度ログインする必要があります。

セッション タイムアウト設定は主に Web で設定されます。これは通常のリクエストです。つまり、ビューとモデルを返すリクエストを開始します。もう 1 つは、主にモデル データを返す Ajax リクエストです。バックエンドが処理を実行するときは、さまざまなリクエストに応じてさまざまなコンテンツを返す必要があります。


通常のリクエストの場合、スクリプトの内容はログインページにジャンプすることができます。

Ajax リクエストの場合、Ajax リクエストがエラー コールバック関数とグローバル Ajax エラー コールバック関数 AjaxError に入るように、200 以外のステータス コードを返す必要があります。

3. バックエンドはセッションタイムアウトを処理します


バックエンドは SpringMVC のインターセプターを使用して処理します。なぜここでインターセプターが使用されるのでしょうか?一方で、リクエスト URL を /* のように制限しすぎることはできません。すべてのリクエストをフィルタリングするのはリソースの無駄です。一方、一部の URL はインターセプトする必要がありません。たとえば、ログイン ページへのリクエストはインターセプトしないでください。インターセプトしないと、ループでリダイレクトされます。一方、インターセプトする必要があるのはコントローラーのリクエストだけであり、他のリクエストは必要ありません。


インターセプターの実装を見てみましょう:

<span style="font-size: 14px;"> <!-- 设置Session超时时间 -->  
    <session-config>  
        <!-- 分钟 -->  
            <session-timeout>60</session-timeout>  
            <!-- 去除URL上显示的jsessionid, 防止打开Tab页时出现JS错误 -->  
            <tracking-mode>COOKIE</tracking-mode>  
    </session-config></span><span style="font-size:24px;">  
</span>
ログイン後にコピー

セッション内の User オブジェクトの存在を取得することで、セッションがタイムアウトしたかどうかを判断します。セッションがタイムアウトした場合は、次に従って戻ります。さまざまなリクエスト方法。通常のリクエストの場合、JavaScript スクリプトが直接返されるため、ページを他の URL にジャンプできます。 Ajax リクエストの場合、401 ステータス コードが返され、返されたヘッダーに sessionTimeout が追加されます。このデータはフロント エンドで使用されます。


インターセプターは SpringMVC 設定ファイルで次のように設定されます:

/** 
* 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
}
ログイン後にコピー

4. フロントエンド処理セッションタイムアウト


通常のリクエストの場合、バックエンドは JavaScript スクリプトを返し、すぐに実行されます。 . ここがフロントエンドです 処理は必要ありません。


Ajax リクエストの場合、バックエンドは 401 ステータス コードとヘッダーに設定された sessionTimeout を返します。ここでは、jQuery の ajaxComplete コールバック関数が次のように使用されます。


<span style="font-size:14px;"><!-- 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 style="font-size:24px;">
</span>
ログイン後にコピー

それでは、セッションがタイムアウトになったユーザーが処理されます。


概要


以上がJavawebプロジェクトのセッションタイムアウトの問題を解決するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート