public class SessionLockControlFilter extends Object implements javax.servlet.Filter
同一セッションの処理を複数スレッドで同時に実行したくない場合に、このフィルタを使用する。
セッションスコープのアクションフォームを使用する場合、同一セッションの処理を複数スレッドで同時に実行すべきではないため、このフィルタを使用する。
(セッションスコープのアクションフォームを使用する場合、同一セッションの処理を複数スレッドで同時に実行されると、入力値検証が通った後、ActionやBLogicの処理に移る前に、アクションフォームが書き換えられる可能性がある。)
このフィルタでは、2つのロック方式を提供している。
LimitedLock
によるロック(ロック待ちスレッドが増えた際に、古いロック待ちスレッドを中断する機能を持つロック)LimitedLock
(しきい値=2)によるロックを使用する。LimitedLock
のロック方式やしきい値、このロック方式の存在意義は、LimitedLock
を参照のこと。
LimitedLock
のしきい値の変更や、synchronizedブロックによるロック方式への切り替えは、このフィルタの初期化パラメータthresholdにて行う。
threshold≧0の場合は、thresholdの値をしきい値として使用し、LimitedLock
によるロックを行う。
threshold<0の場合は、synchronizedブロックによるロックを行う。
※thresholdには整数値を設定すること。
LimitedLock
の機能により、ロック待ちが中断されたスレッドでは、レスポンスとして、特定のレスポンスコードを返すことができる。また、デプロイメントディスクリプタに<error-page>要素を記述することにより、
レスポンスコードに対応するエラーページを割り当てることができる。
ただし、ユーザが同一セッションで複数ウィンドウを操作しない限り、ロック待ちが中断されたスレッドにて、レスポンスに何を返しても、ユーザには見えない。
(最新のリクエストに対するレスポンスだけがブラウザに表示されるが、最新のリクエストを処理しようとしているスレッドは中断対象にならない。ロック待ちが中断されたスレッドは、古いリクエストを処理するものであり、ブラウザはそのレスポンスを無視する。)
デフォルトでは、ロック待ち中断時のレスポンスコードは503(過負荷状態で一時的に処理が実行できない状態であることを表すレスポンスコード)となっている。
レスポンスコードの設定は、このフィルタの初期化パラメータinterruptResponseCodeにて行う。
※interruptResponseCodeには整数値を設定すること。また、このクラスでは値の範囲を制限しないが、JavaEEサーバが使用できるレスポンスコードを設定すること。
<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>
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のロックを解放する。
|
protected int threshold
0以上のとき、LimitedLock
に渡すしきい値となる。
0未満のとき、LimitedLock
を使用せず、synchronizedブロックを使用する。
public void doFilter(javax.servlet.ServletRequest req, javax.servlet.ServletResponse res, javax.servlet.FilterChain chain) throws IOException, javax.servlet.ServletException
doFilter
インタフェース内 javax.servlet.Filter
req
- HTTPリクエストres
- HTTPレスポンスchain
- フィルタチェーンIOException
- I/Oエラーjavax.servlet.ServletException
- サーブレット例外Filter.doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse,
javax.servlet.FilterChain)
protected LimitedLock createLimitedLock()
LimitedLockを拡張した場合、このメソッドをオーバーライドし、LimitedLock拡張クラスのインスタンスを返すよう拡張する。
protected void lockLimitedLock(javax.servlet.http.HttpServletRequest request, LimitedLock lock) throws InterruptedException
ロック取得前後に処理を追加する拡張点。
必要に応じて、このメソッドを拡張すること。
拡張例)
レスポンスを返す前に、任意の場所でロックを解放したい場合等、フィルタ以外から、ロックを取得しているLimitedLockにアクセスしたい場合、ここでLimitedLockをリクエスト属性に設定するよう拡張する。
request
- HTTPリクエストlock
- LimitedLockインスタンスInterruptedException
- 現在のスレッドで割り込みが発生した場合(LimitedLockの機能により、ロック待ちが中断された場合を含む)protected void unlockLimitedLock(javax.servlet.http.HttpServletRequest request, LimitedLock lock)
ロック解放前後に処理を追加する拡張点。
必要に応じて、このメソッドを拡張すること。
request
- HTTPリクエストlock
- LimitedLockインスタンスpublic void init(javax.servlet.FilterConfig config) throws javax.servlet.ServletException
init
インタフェース内 javax.servlet.Filter
config
- FilterConfigインスタンス。javax.servlet.ServletException
- 初期化異常時にスローされる例外。Filter.init(javax.servlet.FilterConfig)
,
AbstractControlFilter
public void destroy()
destroy
インタフェース内 javax.servlet.Filter
Filter.destroy()
Copyright © 2014. All Rights Reserved.