jp.terasoluna.fw.web.thin
クラス SessionLockControlFilter

java.lang.Object
  上位を拡張 jp.terasoluna.fw.web.thin.SessionLockControlFilter
すべての実装されたインタフェース:
javax.servlet.Filter

public class SessionLockControlFilter
extends java.lang.Object
implements javax.servlet.Filter

同一セッションの処理の同期化を行う。

同一セッションの処理を複数スレッドで同時に実行したくない場合に、このフィルタを使用する。
セッションスコープのアクションフォームを使用する場合、同一セッションの処理を複数スレッドで同時に実行すべきではないため、このフィルタを使用する。
(セッションスコープのアクションフォームを使用する場合、同一セッションの処理を複数スレッドで同時に実行されると、入力値検証が通った後、ActionやBLogicの処理に移る前に、アクションフォームが書き換えられる可能性がある。)

このフィルタでは、2つのロック方式を提供している。

デフォルトでは、LimitedLock(しきい値=2)によるロックを使用する。
LimitedLockのロック方式やしきい値、このロック方式の存在意義は、LimitedLockを参照のこと。

LimitedLockのしきい値の変更や、synchronizedブロックによるロック方式への切り替えは、このフィルタの初期化パラメータthresholdにて行う。
threshold≧0の場合は、thresholdの値をしきい値として使用し、LimitedLockによるロックを行う。
threshold<0の場合は、synchronizedブロックによるロックを行う。
※thresholdには整数値を設定すること。

LimitedLockの機能により、ロック待ちが中断されたスレッドでは、レスポンスとして、特定のレスポンスコードを返すことができる。また、デプロイメントディスクリプタに<error-page>要素を記述することにより、 レスポンスコードに対応するエラーページを割り当てることができる。
ただし、ユーザが同一セッションで複数ウィンドウを操作しない限り、ロック待ちが中断されたスレッドにて、レスポンスに何を返しても、ユーザには見えない。
(最新のリクエストに対するレスポンスだけがブラウザに表示されるが、最新のリクエストを処理しようとしているスレッドは中断対象にならない。ロック待ちが中断されたスレッドは、古いリクエストを処理するものであり、ブラウザはそのレスポンスを無視する。) デフォルトでは、ロック待ち中断時のレスポンスコードは503(過負荷状態で一時的に処理が実行できない状態であることを表すレスポンスコード)となっている。
レスポンスコードの設定は、このフィルタの初期化パラメータinterruptResponseCodeにて行う。
※interruptResponseCodeには整数値を設定すること。また、このクラスでは値の範囲を制限しないが、JavaEEサーバが使用できるレスポンスコードを設定すること。

使用方法
この機能を使用するにはデプロイメントディスクリプタ(web.xml)に以下のように 設定する。

 <filter>
   <filter-name>sessionLockControlFilter</filter-name>
   <filter-class>jp.terasoluna.fw.web.thin.SessionLockControlFilter</filter-class>
   <init-param>
     <param-name>interruptResponseCode</param-name>
     <param-value>503</param-value>
   </init-param>
   <init-param>
     <param-name>threshold</param-name>
     <param-value>2</param-value>
   </init-param>
 </filter>
 
 <filter-mapping>
   <filter-name>sessionLockControlFilter</filter-name>
   <url-pattern>*.do</url-pattern>
 </filter-mapping>
 
 <error-page>
   <error-code>503</error-code>
   <location>/error.jsp</location>
 </error-page>
 

なお、各初期化パラメータにおいて、デフォルト値(interruptResponseCode=503、threshold=2)を利用する場合は、 デプロイメントディスクリプタ (web.xml)内の<filter>要素から<init-param>要素を省略することができる。
また、エラーページを設定しない場合は、<error-page>要素を省略することができる。

関連項目:
LimitedLock

フィールドの概要
private static int DEFAULT_INTERRUPT_RESPONSE_CODE
          初期化パラメータinterruptResponseCodeのデフォルト値(503)。
private static int DEFAULT_THRESHOLD
          初期化パラメータthresholdのデフォルト値(2)。
private static java.lang.String INIT_PARAM_INTERRUPT_RESPONSE_CODE
          初期化パラメータ名:interruptResponseCode。
private static java.lang.String INIT_PARAM_THRESHOLD
          初期化パラメータ名:threshold。
private  int interruptResponseCode
          初期化パラメータinterruptResponseCode。
private  java.util.concurrent.ConcurrentHashMap<java.lang.String,SessionLockReference> limitedLockMap
          LimitedLockの弱参照マップ。
private static org.apache.commons.logging.Log log
          ログクラス。
private  java.lang.ref.ReferenceQueue<LimitedLock> sessionLockRefQueue
          セッション同期に用いているLimitedLockの参照キュー。
protected  int threshold
          初期化パラメータthreshold。
 
コンストラクタの概要
SessionLockControlFilter()
           
 
メソッドの概要
protected  LimitedLock createLimitedLock()
          LimitedLockインスタンスを生成する。
 void destroy()
          サービス状態を終えた事をフィルタに伝えるために、コンテナが呼び出す。
 void doFilter(javax.servlet.ServletRequest req, javax.servlet.ServletResponse res, javax.servlet.FilterChain chain)
          同一セッションの処理の同期化を行う。
 void init(javax.servlet.FilterConfig config)
          フィルタがサービス開始状態になる際に、コンテナによって呼び出される。
protected  void lockLimitedLock(javax.servlet.http.HttpServletRequest request, LimitedLock lock)
          LimitedLockのロックを取得する。
protected  void unlockLimitedLock(javax.servlet.http.HttpServletRequest request, LimitedLock lock)
          LimitedLockのロックを解放する。
 
クラス java.lang.Object から継承されたメソッド
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

フィールドの詳細

log

private static final org.apache.commons.logging.Log log
ログクラス。


INIT_PARAM_INTERRUPT_RESPONSE_CODE

private static final java.lang.String INIT_PARAM_INTERRUPT_RESPONSE_CODE
初期化パラメータ名:interruptResponseCode。

関連項目:
定数フィールド値

INIT_PARAM_THRESHOLD

private static final java.lang.String INIT_PARAM_THRESHOLD
初期化パラメータ名:threshold。

関連項目:
定数フィールド値

DEFAULT_INTERRUPT_RESPONSE_CODE

private static final int DEFAULT_INTERRUPT_RESPONSE_CODE
初期化パラメータinterruptResponseCodeのデフォルト値(503)。

関連項目:
定数フィールド値

DEFAULT_THRESHOLD

private static final int DEFAULT_THRESHOLD
初期化パラメータthresholdのデフォルト値(2)。

関連項目:
定数フィールド値

interruptResponseCode

private int interruptResponseCode
初期化パラメータinterruptResponseCode。

ロック待ち中断時のレスポンスコード。


threshold

protected int threshold
初期化パラメータthreshold。

0以上のとき、LimitedLockに渡すしきい値となる。
0未満のとき、LimitedLockを使用せず、synchronizedブロックを使用する。


sessionLockRefQueue

private java.lang.ref.ReferenceQueue<LimitedLock> sessionLockRefQueue
セッション同期に用いているLimitedLockの参照キュー。

セッション同期に用いているLimitedLockインスタンスが参照されなくなり、ガベージコレクタに回収されるとき、ガベージコレクタによって、 LimitedLockインスタンスを保持していた SessionLockReferenceがこの参照キューに追加される。
limitedLockMap内で不要になったエントリーを削除する際に利用する。


limitedLockMap

private java.util.concurrent.ConcurrentHashMap<java.lang.String,SessionLockReference> limitedLockMap
LimitedLockの弱参照マップ。

キーはセッションID、値は、LimitedLockへの弱参照であるSessionLockReference
あるセッションID用にLimitedLockインスタンスを用意した場合、SessionLockReferenceにラップしてからこのマップにputする。
この、あるセッションID用に用意したLimitedLockが、いずれかのスレッドで使用中である場合、 このマップから、そのセッションIDをキーにSessionLockReferenceが、さらに、 SessionLockReferenceから、そのセッションID用のLimitedLockが取得可能である。
この、あるセッションID用に用意したLimitedLockを、どのスレッドも参照していないとき、このLimitedLockはガベージコレクタによって回収可能となる。
LimitedLockがガベージコレクタに回収された場合、このマップから得られたSessionLockReferenceからは、LimitedLockを得ることができない。
この場合、LimitedLockが取得できないエントリーが一時的に残るが、sessionLockRefQueueと連携することにより、不要になったエントリーは、じきに削除される。

コンストラクタの詳細

SessionLockControlFilter

public SessionLockControlFilter()
メソッドの詳細

doFilter

public void doFilter(javax.servlet.ServletRequest req,
                     javax.servlet.ServletResponse res,
                     javax.servlet.FilterChain chain)
              throws java.io.IOException,
                     javax.servlet.ServletException
同一セッションの処理の同期化を行う。

定義:
インタフェース javax.servlet.Filter 内の doFilter
パラメータ:
req - HTTPリクエスト
res - HTTPレスポンス
chain - フィルタチェーン
例外:
java.io.IOException - I/Oエラー
javax.servlet.ServletException - サーブレット例外
関連項目:
Filter.doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)

createLimitedLock

protected LimitedLock createLimitedLock()
LimitedLockインスタンスを生成する。

LimitedLockを拡張した場合、このメソッドをオーバーライドし、LimitedLock拡張クラスのインスタンスを返すよう拡張する。

戻り値:
LimitedLockインスタンス

lockLimitedLock

protected void lockLimitedLock(javax.servlet.http.HttpServletRequest request,
                               LimitedLock lock)
                        throws java.lang.InterruptedException
LimitedLockのロックを取得する。

ロック取得前後に処理を追加する拡張点。
必要に応じて、このメソッドを拡張すること。

拡張例)
レスポンスを返す前に、任意の場所でロックを解放したい場合等、フィルタ以外から、ロックを取得しているLimitedLockにアクセスしたい場合、ここでLimitedLockをリクエスト属性に設定するよう拡張する。

パラメータ:
request - HTTPリクエスト
lock - LimitedLockインスタンス
例外:
java.lang.InterruptedException - 現在のスレッドで割り込みが発生した場合(LimitedLockの機能により、ロック待ちが中断された場合を含む)

unlockLimitedLock

protected void unlockLimitedLock(javax.servlet.http.HttpServletRequest request,
                                 LimitedLock lock)
LimitedLockのロックを解放する。

ロック解放前後に処理を追加する拡張点。
必要に応じて、このメソッドを拡張すること。

パラメータ:
request - HTTPリクエスト
lock - LimitedLockインスタンス

init

public void init(javax.servlet.FilterConfig config)
          throws javax.servlet.ServletException
フィルタがサービス開始状態になる際に、コンテナによって呼び出される。 コンテナは、Filterをインスタンス化した後に、initメソッドを 1 回だけ呼び出す。
Filterにフィルタ処理作業を実行するように要求するには、 init メソッドが正常に 終了していなければならない。 initメソッドが 次のいずれかの状態の場合、コンテナは Filterをサービス状態にできない。

定義:
インタフェース javax.servlet.Filter 内の init
パラメータ:
config - FilterConfigインスタンス。
例外:
javax.servlet.ServletException - 初期化異常時にスローされる例外。
関連項目:
Filter.init(javax.servlet.FilterConfig), AbstractControlFilter

destroy

public void destroy()
サービス状態を終えた事をフィルタに伝えるために、コンテナが呼び出す。
このクラスでは処理は行なわない。

定義:
インタフェース javax.servlet.Filter 内の destroy
関連項目:
Filter.destroy()