2013-01-04 38 views
5

私はいつ知りたいのですか正確に HttpSessionはになります(破損と同じではありません)?私はsession.getLastAccessedTime()+(session.getMaxInactiveInterval()* 1000)私の要求が同じセッションIDが付属していますたびに、セッションの有効期限をミリ秒単位で正確な時間を与える場合は!把握しようとしていますHttpSessionが期限切れになったとき(破棄の対象となり始めるが、必ずしも破壊される必要はない)?

javadocから

長いgetLastAccessedTime()

Returns the last time the client sent a request associated with this session, as the number of milliseconds since midnight January 1, 1970 GMT, and marked by the time the container received the request.  

int型getMaxInactiveInterval()

Returns the maximum time interval, in seconds, that the servlet container will keep this session open between client accesses. 

には、以下の我々が持っているとしましょう:
Treq1 - the time the container received the 1st request(HttpSession.lastAccessedTime)
Tresp1 - the time the container sends the 1st response
Preq1 - the time period between Treq1 and Tresp1 (the time period that the server processes the 1st request
Treq2 - the time the container received the 2nd request(HttpSession.lastAccessedTime)
Preq1req2 - the time period between Treq1 and Treq2 (the time between requests entering the container)
Presp1req2 - the time period between Tresp1 and Treq2 (the time between the 1st response exiting the container and the 2nd request entering the container)

だから今、サーバが計算しませんセッションは期限切れですか?
1 Treq1 + maxInactiveInterval < Treq1 + Preq1req2 =>maxInactiveInterval < Preq1req2
2 Tresp1 + maxInactiveInterval < Tresp1 + Presp1req2 =>maxInactiveInterval < Presp1req2

この部分、the servlet container will keep this session open between client accessesであります少し紛らわしい。コンテナに入る要求間、または応答の終了と要求の入力の間に意味がありますか?サイドノートで

私はセッションが期限切れの正確な時に破壊されない可能性があることを知っているが、いずれの要求処理ロジックがで発生する前に、それが破壊された場合、私はまだ知りませんコンテナ期限切れのセッションIDを保持しているリクエストを参照しています。

種類よろしく、
専制君主

+1

なぜ重要ですか?要求の時間は、通常、数ミリ秒である。セッションタイムアウトは通常30分です。 30.000か30.002かどうかは重要ですか?あなたの最終目標は何ですか? * –

+0

クライアントがセッションが期限切れになる時刻を正確に知りたいので、重要です。 "答えは質問にあります:コンテナが要求を受け取った時点でマークされています"これはlastAccessedTimeを参照するだけかもしれません。有効期限がsession.getLastAccessedTime()+(session.getMaxInactiveInterval()* 1000)(1. case)になることは確かですか?それを確認できる情報源はありますか?コメントありがとう! – despot

+2

これはミリ秒に正確にしたいですか? 30分後、30分後、8ミリ秒後のエンドユーザのケアはありますか?とにかく、コンテナは通常1分ごとに期限切れのセッションを破棄するバックグラウンドスレッドを使用するため、その時点でセッションは破棄されません。 –

答えて

10

セッション機構が義務付けServlet specificationの一部である:

をHTTPプロトコルでは、クライアントはアクティブもはや ない場合、明示的な終了信号が存在しません。つまり、 クライアントがアクティブでなくなったときを示すために使用できる唯一のメカニズムはタイムアウト期間です。

セッションのデフォルトのタイムアウト時間はサーブレットコンテナによって定義され、 はHttpSessionインターフェイスのgetMaxInactiveIntervalメソッドで取得できます。 このタイムアウトは、開発者がHttpSessionインターフェイスのsetMaxInactiveInterval メソッドを使用して変更できます。これらのメソッドで使用されるタイムアウト時間は秒単位で定義されています( )。セッションのタイムアウト時間が-1に設定されている場合、セッションは期限切れになりません。セッション無効化は、そのセッションを使用しているすべてのサーブレットがサービスメソッドを終了するまで有効になりません。セッション の無効化が開始されると、新しい要求がそのセッションを見ることができなくてはなりません。

HttpSessionインターフェイスのgetLastAccessedTimeメソッドを使用すると、サーブレットは に、現在の要求より前にセッションにアクセスした最後の時刻を特定できます。 セッションは、セッションの一部である要求がサーブレットコンテナによって最初に処理されるときにアクセスされると見なされます( )。

「非アクティブ間隔」が「lastAccessedTime」で始まると想定するのはおそらく安全でしょう。

+0

OK、セッションの有効期限はsession.getLastAccessedTime()+(session.getMaxInactiveInterval()* 1000)で計算する必要があり、ケース1は正しいですか? – despot

+0

私は上記を仮定するつもりです。 – despot

+0

引用の最後の部分には「...現在の要求より前にセッションがアクセスされた最後の時刻を特定する_」が含まれています。私には、今回は現在の要求ではなく、その前の要求であることを意味します。したがって、セッションの終了時刻を決定するには、リクエストの開始時に@Subinの答えのようにmaxInactiveIntervalに現在の時刻を追加する必要があります。 – cyberbrain

3

私はsession.getLastAccessedTime()+(session.getMaxInactiveInterval()* 1000)は私のセッションの有効期限のミリ秒毎の正確な時間を与えるかどうかを把握しようとしていますリクエストには同じセッションIDが付いています。

あなただけの私がタイムアウトカウンタであってもよいし、あなたは彼が彼の次のクリックする前に取ることができます何時にクライアント(ブラウザ)を通知するためのサーブレットのコードの上に持っていると仮定しています要求スレッドでセッションオブジェクトにアクセスすることができますので、 。

この場合、System.currentTimeMillis() + (session.getMaxInactiveInterval() * 1000)はより正確になります。

+0

"クライアント(ブラウザ)に正確に通知するため"です。 "私はSystem.currentTimeMillis()+(session.getMaxInactiveInterval()* 1000)"と仮定しているので、あなたはそれが2の場合を想定していますか?どんな情報源であれ、私たちはこれを確かめることができますか?ご回答有難うございます! – despot

+0

これを人間が判読可能な形式で表示する場合は、次のように使用できます。SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss.SSS");日付resultdate =新しい日付(timeInMs); System.out.println( "HRFの日付:" + sdf.format(resultdate)); –

0

ソース?

は、私が二回使用して要求をトレースし spring「:春・ブート・スターター・ウェブorg.springframework.boot 1.5.6.RELEASEを」と結論づけ:あなたのサービス・ハンドラ(doGetメソッド、doXX、またはコントローラのメソッドで

をlastAccessedTimeがサービス後に更新されている場合)、有効期限がsession.getLastAccessedTime() + (session.getMaxInactiveInterval() * 1000)(2ケース)

Duration:  |<---------- Preq1req2 ---------->| 
Duration:  |   |<---- Presp1req2 --->| 
Time :  Treq1  Tresp1    Treq2  Tresp2 
Action : req1-->|--service--|-->resp1 ... req2-->|--service--|-->resp2 
Duration:  |<- Preq1 ->|      |<- Preq2 ->| 
       |   |         | 
Set :  creationTime  |         | 
      lastAccessedTime |         |    
         lastAccessedTime     lastAccessedTime 

になるだろう:Cから After HTTP service

コードスニペット:/会社ERS/ssfang/.m2 /リポジトリ/ ORG /のApache/Tomcatの/は/ Tomcatの-組み込むコア/ 8.5.16/Tomcatの-埋め込みコア8.5.16-sources.jar埋め込む

package org.apache.catalina.session; 
public class StandardSession implements HttpSession, Session, Serializable { 
    /** The time this session was created, in milliseconds since midnight, January 1, 1970 GMT. */ 
    protected long creationTime = 0L; 

    /** 
    * We are currently processing a session expiration, so bypass 
    * certain IllegalStateException tests. NOTE: This value is not 
    * included in the serialized version of this object. 
    */ 
    protected transient volatile boolean expiring = false; 

    /** The last accessed time for this Session. */ 
    protected volatile long lastAccessedTime = creationTime; 

    /** The session event listeners for this Session. */ 
    protected transient ArrayList<SessionListener> listeners = new ArrayList<>(); 

    /** Flag indicating whether this session is valid or not. */ 
    protected volatile boolean isValid = false; 

    /** The current accessed time for this session. */ 
    protected volatile long thisAccessedTime = creationTime; 


    /** The access count for this session. */ 
    protected transient AtomicInteger accessCount = null; 

    /** 
    * The maximum time interval, in seconds, between client requests before the servlet container may 
    * invalidate this session. A negative time indicates that the session should never time out. 
    */ 
    protected volatile int maxInactiveInterval = -1; 

    /** 
    * Return the idle time from last client access time without invalidation check 
    * @see #getIdleTime() 
    */ 
    @Override 
    public long getIdleTimeInternal() { 
     long timeNow = System.currentTimeMillis(); 
     long timeIdle; 
     if (LAST_ACCESS_AT_START) { 
      timeIdle = timeNow - lastAccessedTime; 
     } else { 
      timeIdle = timeNow - thisAccessedTime; 
     } 
     return timeIdle; 
    } 

    /** 
    * Set the creation time for this session. This method is called by the 
    * Manager when an existing Session instance is reused. 
    * 
    * @param time The new creation time 
    */ 
    @Override 
    public void setCreationTime(long time) { 
     this.creationTime = time; 
     this.lastAccessedTime = time; 
     this.thisAccessedTime = time; 
    } 

    /** Return the <code>isValid</code> flag for this session. */ 
    @Override 
    public boolean isValid() { 
     if (!this.isValid) { 
      return false; 
     } 
     if (this.expiring) { 
      return true; 
     } 
     if (ACTIVITY_CHECK && accessCount.get() > 0) { 
      return true; 
     } 
     if (maxInactiveInterval > 0) { 
      int timeIdle = (int) (getIdleTimeInternal()/1000L); 
      if (timeIdle >= maxInactiveInterval) { 
       expire(true); 
      } 
     } 
     return this.isValid; 
    } 
} 

かどうかを確認セッションは、セッションに有効期限が切れているかどうかをすべてのセッションをスキャンするバックグラウンドスレッド

Check whether the session is valid before getting the session

を取得する前に有効です。

background thread to scan sessions

関連する問題