ページの先頭行へ戻る
 Apcoordinatorユーザーズガイド

17.1.5 高度なセション管理

Webcoordinatorでは、通常のセション管理に加えて、以下の機能を利用することができます。

URLリライティングを使用する

JSPでは一般的にはCookieを使用してセション管理を行います。携帯電話などのCookieを利用できない環境を対象とする場合は、URLリライティングを使用してセション管理を行います。

二重処理を防止する

ブラウザの画面でボタンを連続して押した場合に、サーバへのリクエストが2度続けて発行される場合があります。このとき、処理が二重に実行されることを防止します。

セションを明示的に切断する

タイムアウトを待たずにセションを切断することができます。

二重処理を防止する方法には以下の2つがあり、機能が有効になる範囲に違いがあります。

セションクラスにHttpControlStateProfileクラスを使う

HttpControlStateProfileクラスを継承してセションクラスを作成する方法です。uji:dispatchタグ動作中は二重処理が防止されます。ビジネスクラスはuji:dispatchタグの動作中に実行されるため、ビジネスクラス実行中の二重処理が防止できます。

uji:formタグのpostOnceアトリビュートを使う

uji:formタグのpostOnceアトリビュートにtrueを指定すると、フォームの送信を1回のみに制限します。この場合、二重処理はブラウザ上で防止され、2回目以降のリクエストはサーバに送信されません。ただし、JavaScriptを使用して実現しているため、JavaScriptを無効にしているブラウザでは動作しません。

uji:formタグによる二重処理の防止機能は、“uji:formタグのpostOnceアトリビュートの使用方法”で説明します。

注意

Apcoordinator V5.0L10、INTERSTAGE WEBCOORDINATORで提供していたuji:controlSectionタグは提供されません。uji:controlSectionタグを使ったJSPは修正しなくても実行できますが、 uji:controlSectionタグを使用しない場合と同じ動作となります。詳細は“付録C 旧バージョンとの互換情報”を参照してください。

HttpControlStateProfileクラスの使用方法

HttpControlStateProfileクラスを使用すると以下の機能が実現できます。

これらの機能を利用する場合には、以下の手順でアプリケーションを作成します。

  1. 全てのHTMLフォームにuji:controlStateタグを追加します。

    <FORM>
       <uji:controlState />
       ...
    </FORM>
  2. セションクラスをHttpControlStateProfileから継承します。

    package sample;
    public class SampleSession extends com.fujitsu.uji.http.HttpControlStateProfile
    {
    }
  3. セションクラスで、機能に対応したメソッドをオーバライドして、必要なパラメタを返却します。

    • URLリライティングを使用する場合は、getSessionModeメソッドをオーバライドします。

          public int getSessionMode() {
              return HttpControlStateProfile.URLREWRITING;
          }

      リクエストに対してCookie使用かURLリライティング使用かを動的に切り替えることはできません。

      リダイレクトロケーションURLにパラメタを付加する場合は、getRedirectURLメソッドをオーバライドします。

          public String getRedirectURL(String defaultUrl) {
              return defaultUrl + "?addparam";
          }

      注意

      URLリライティング機能では、javax.servlet.http.encodeURLクラスのencodeURLメソッドを利用しています。

      URLにセションIDを付けるかどうかは、アプリケーションサーバのencodeURLメソッドの実装に依存します。

      そのため、URLリライティング機能を利用している場合でも、URLにセションIDが付かない場合があります。

    • 二重処理を防止する場合は、isDoublePostEnabledメソッドをオーバライドします。

          public boolean isDoublePostEnabled() {
              return false;
          }

      1個目のリクエストに対する処理を実行中に2個目のリクエストを受け取った場合は、2個目のリクエストに対する処理は実行せず、1度目の処理の結果を2度目のリクエストに対して返却します。

      デフォルトではPOSTメソッドによるリクエストに対して二重処理を防止します。 GETメソッドによるリクエストの二重処理も防止する場合は、初期化パラメタuji.doublegetdisabledを設定してください。

      注意

      • 二重処理機能を用いた場合でも完全に二重処理を防止することは出来ません。例えば、レスポンスが通信路上を流れているときにリクエストが送信された場合は、サーバ側でそれが次のリクエストであるか、二重処理のリクエストであるかを判断することはできません。できる限り二重処理を防止したい場合はuji:formタグのpostOnceアトリビュートと併用してください。

      • ウィンドウ制御機能、フレーム制御機能を使用する場合で、異なるウィンドウもしくはフレームから二重にリクエストを送信した場合は、最初にサーバに到達したリクエストでビジネスクラスが実行されます。後に送信したリクエストはビジネスクラスを実行しないため画面は更新されません。

      • 二重処理のリクエストの送信先で、一方がJSP、一方がServletの場合は正しく画面を返すことができません。同一画面からのリクエストはすべてJSPかServletのどちらかに統一してください。

    • リクエストの検証については、“17.1.8 リクエストの検証”を参照してください。

セションを明示的に切断する方法

セションを切断するには、HttpSessionProfileクラスのdisposeメソッドをビジネスクラスから呼び出します。

    public void finalHandler(DispatchContext context, SomeBean dataBean) {
        ....
        context.setResponseBean("body", dataBean);

        HttpSessionProfile sp = 
            (HttpSessionProfile)context.getSessionProfile();
        sp.dispose();
    }

disposeの呼び出しにより、サーブレットコンテナが管理するセションの情報 (javax.servlet.http.HttpSession) からセションクラスが削除されます。 Webcoordinatorがセションに関連づけて管理する情報はセションクラスに格納されているため、それらの情報もセションクラスと共にセションから削除されます。サーブレットコンテナが管理するセションとHttpSessionは存続します。 dispose実行後最初にリクエストを受けたタイミングで新しいセションクラスが作成されます。

uji:formタグのpostOnceアトリビュートの使用方法

uji:formタグのpostOnceアトリビュートによる二重処理の防止機能は、同じ画面から再度フォームを送信することを防ぎます。この機能はJavaScriptを利用して、フォーム送信時にフラグを立てることにより実現されます。JavaScriptを無効にしてあるブラウザでは動作しません。

uji:formタグで二重処理を防止するには、uji:formタグでフォームを作成し、postOnceアトリビュートに"true"を指定します。

<uji:form name="order" method="post" postOnce="true" verbs="ok,cancel" beanId="body" 
  beanCls="my.pkg.MyDataBean">
    商品コード: <INPUT NAME="code"><BR>
    個数:       <INPUT NAME="count"><BR>
    <INPUT TYPE="SUBMIT" NAME="ok" VALUE="決定">
    <INPUT TYPE="SUBMIT" NAME="cancel" VALUE="キャンセル"> 
</uji:form>

postOnce="true"を指定した場合、ブラウザの読み込みが中断されたあとでも二重処理防止機能が有効になっています。そのため、次の画面が表示される前に読み込み停止ボタンなどを押して送信処理を中断し、そのあとで送信ボタンを押した場合はフォームが送信されません。このような状態に備えて、postOnce="true"の指定の有無にかかわらずフォームが送信できる送信ボタンを作成できます。送信ボタンをuji:pushButtonタグで作成し、skipScript="true"を指定してください。

<uji:form name="order" method="post" postOnce="true" verbs="ok,cancel" beanId="body" 
  beanCls="my.pkg.MyDataBean">
    商品コード: <INPUT NAME="code"><BR>
    個数:       <INPUT NAME="count"><BR>
    <INPUT TYPE="SUBMIT" NAME="ok" VALUE="決定">
    <uji:pushButton type="submit" name="cancel" label="キャンセル" skipScript="true" /> 
</uji:form>

skipScript="true"の指定は、フォーム送信時のJavaScriptの実行を抑止するための機能です。この指定のあるボタンが押された場合は、二重処理を防止するJavaScriptだけでなく、入力値をチェックするJavaScriptも実行されません。