ブラウザのキャッシュ内の画面が再利用されることにより、予期しないページからリクエストが送信される場合があります。これをApcoordinatorで検出することができます。予期しない画面からのリクエストを検出することを、以降では、リクエストの正当性検査と呼びます。
ブラウザの仕様に依存しますが、以下の場合には再利用された画面からリクエストが送信されることがあります。
ブラウザの「戻る」ボタンを押すと、キャッシュ内の画面が再度表示されます。この状態で送信ボタンなどによりフォームを送信すると、再利用された画面からリクエストが送信される結果となります。
過去にGETメソッドによるリクエストを送信して画面を取得したことがある場合、そのリクエストと同じURLでアクセスした場合に画面が再利用されることがあります。この状態でフォームを送信すると、再利用された画面からリクエストが送信される結果となります。
リクエストの正当性検査により、上記のようなリクエストが検出できます。
リクエストの正当性検査を有効にすると、Apcoordinatorによって以下の処理が行なわれます。
Webアプリケーションが最後にブラウザに送信した画面からリクエストを受信した場合は、ビジネスクラスの呼び出しを実行します。
それ以外の画面からのリクエストを受信した場合は、ControlStateExceptionをスローします。このとき、ビジネスクラスは呼び出されません。
リクエストの正当性検査を有効にするには、アプリケーションを以下のように作成します。
ユーザー定義のセションクラスを作成する
ユーザー定義のセションクラスをcom.fujitsu.uji.http.HttpControlStateProfileクラスを継承して作成します。また、isPageCheckEnabled メソッドをオーバライドしてtrueを返却するようにします。このメソッドは、リクエストの正当性検査を有効にするかどうかを指定するものです。
public class SampleSession extends com.fujitsu.uji.http.HttpControlStateProfile { public boolean isPageCheckEnabled() { return true; } }
なお、ユーザー定義のセションクラスを有効にするために、以下の作業が必要になります。具体的な方法は“3.5 ファクトリクラス”を参照してください。
ファクトリクラスを作成し、ユーザー定義セションクラスのオブジェクトが作成されるようにします。
初期化パラメタでファクトリクラスのクラス名を指定します。Webアプリケーションの初期化パラメタはWebアプリケーション環境定義ファイル(web.xml)に記述します。
フォームにuji:controlStateタグを追加する
すべてのフォームにuji:controlStateタグを追加します。 1画面に複数のフォームがある場合、全てのフォームにuji:controlStateを記述してください。
<uji:form ...>
<uji:controlState />
...
</uji:form>
予期されないページからのリクエストを検出した場合の処理を追加する
Webアプリケーションが最後に送信した画面以外からリクエストが送信された場合、com.fujitsu.uji.ControlStateExceptionが発生します。この例外をキャッチして処理を実行するには、セションクラスまたはアプリケーションクラスのhandleExceptionメソッドに処理を記述してください。例外が発生すると、handleExceptionメソッドが呼び出されます。
セションクラスに例外処理を追加する例
import com.fujitsu.uji.ControlStateException;
import com.fujitsu.uji.DispatchContext;
import com.fujitsu.uji.http.HttpControlStateProfile;
public class SampleSession extends HttpControlStateProfile {
public boolean isPageCheckEnabled() {
return true;
}
public Object handleException(DispatchContext context, Throwable th) throws Throwable {
if (th instanceof ControlStateException) { // (1)
context.setResponseBean("body", new ErrorBean()); // (2)
} else {
throw th; // (3)
}
return null;
}
}
この例では、予期されないページからリクエストがあった場合にユーザーが定義したエラーページを表示させます。処理の内容は次のとおりです。
(1) 発生した例外はhandleExceptionの引数thに与えられます。例外がControlStateExceptionの場合のみ、目的の処理を実行するようにプログラムします。handleExceptionは、ビジネスクラスの呼び出しで発生した例外をまとめて処理するためのメソッドであり、ControlStateException以外の例外が引数に与えられる場合があります。
(2) ユーザー定義のエラー画面を表示させるため、エラー画面用のデータBeanを適切な領域に割り当てます。
(3) ControlStateException以外の例外は再度スローするか、例外の種類に応じた適切な処理を行ないます。
ポイント
サブウィンドウを利用したアプリケーションでリクエストの正当性検査を行う場合は、ウィンドウ制御機能を使ってサブウィンドウの表示を制御してください。また、フレームを利用したアプリケーションの場合は、uji:frameタグを使ってフレームを作成してください。ウィンドウ制御機能やuji:frameタグを使った場合、リクエストの正当性検査は各ウィンドウ、各フレームごとに行われます。
ウィンドウ制御機能やuji:frameタグを使わずにサブウィンドウやフレームを作成し、かつ、リクエストの正当性検査を行う場合は、いずれか一つのウィンドウまたはフレームだけでリクエストの正当性検査を行うことができます。検査を行うウィンドウやフレームにはuji:controlStateタグを記述し、それ以外のウィンドウやフレームに表示されるフォームにはuji:controlStateタグを記述しないでください。
関連項目