連載
» 2009年01月21日 00時00分 公開

Webアプリの常識をJSPとStrutsで身につける(6):発掘! Webの“あるある”問題点−ステートの常識 (2/3)

[眞野寿彦,株式会社メセナ・ネットコム]

Cookieの情報を使ってみよう

 では、実際にCookie情報を利用した画面を作成してみましょう。

 なお、今回もサンプルプログラムは、連載第2回で使用した「PKG」のワークスペースを使います。「PKG\Hello\pages」配下に下記のJSPファイルを作成してください。

Session.jsp
<%@ page contentType="text/html; charset=Shift-JIS" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<script type="text/javascript">
<!--
    cokkie = getCookie("Cookie");

    if (cokkie == "") {
        cokkie = 1;
    }else{
        cokkie++;
    }
    document.cookie ="Cookie=" + cokkie;

    function getCookie(key, tmp1, tmp2, xx1, xx2, xx3) {
        tmp1 = " " + document.cookie + ";";
        xx1 = xx2 = 0;
        len = tmp1.length;
        while (xx1 < len) {
            xx2 = tmp1.indexOf(";", xx1);
            tmp2 = tmp1.substring(xx1 + 1, xx2);
            xx3 = tmp2.indexOf("=");
            if (tmp2.substring(0, xx3) == key) {
                return(unescape(tmp2.substring(
                    xx3 + 1, xx2 - xx1 - 1)));
            }
            xx1 = xx2 + 1;
        }
        return("");
    }
// -->
</script>
<html:html>
  <head><title>Session/Cookieサンプル</title></head>
  <html:form action="/hello">
    <bean:cookie id="Data" name="Cookie" value="NoData"/>
    <table border="0">
      <tr><td>
        クッキーの値:<bean:write name="Data" property="value" />
      </td></tr>
    </table>
  </html:form>
</html:html>

 画面の作成が完了したところで、早速表示させて確認してみましょう。連載第2回と同様に、Eclipseを起動します。次に、[プロジェクト・エクスプローラー]の「Hello」を選択して右クリックをして、[リフレッシュ]を選択します。Eclipseで[プロジェクト]の[クリーン]を選択して、Helloプロジェクトのコンパイルが完了したら、Eclipse上から「Tomcat起動」アイコン(猫マーク)を押して、Tomcatを起動してください。

 正常に起動したことを確認したら、「http://localhost:8080/hello/pages/Session.jsp」にアクセスしてください。すると、下記のような画面が表示されます。

図1 Cookieの値を表示 図1 Cookieの値を表示

 「クッキーの値」には、「NoData」と表示されていると思います。

 では、Webブラウザ(ここでは、Internet Explorer 7)の[メニューバー]から[表示]の[最新の情報に更新](または、[F5]キー)を選択してみてください。すると、下記のような画面が表示されたかと思います。

図2 Cookieの値に変化が! 図2 Cookieの値に変化が!

 「クッキー値」の情報が「1」に変わったのが分かると思います。これは、1度目の画面を開いた際に、JavaScriptでCookie情報を保持しているため、2度目でクッキーの情報の表示が変わったのです。さらに説明すると、2度目の情報でCookie情報をカウントアップしている処理を設定しています。そのため、Webブラウザを更新し続けると、クッキー値の情報が「2、3、4、……」と表示されていきます。

<bean:cookie>タグ

 <bean:cookie>タグは、Strutsのカスタムタグの1つで、項目「クッキー値」の値であるクッキー情報を取り出し、Cookieオブジェクトを「page」スコープにセットするタグです(スコープについては、コラム「スクリプティング変数とスコープ」を参照)。<bean:cookie>の初期値は属性「value」で指定します。属性「name」でCookieオブジェクトから取り出したいCookie名を指定して情報を取り出します。

コラム 「同期と非同期」

データ通信システムで通信を行う場合、送信側と受信側が同じタイミングでデータのやりとりを行う必要があり、このタイミングを取ることを「同期」といいます。

システムでのデータ通信は、「同期」型と「非同期型に分類できます。Webサービスで考えた場合、同期は、サーバへリクエストを送信してからクライアントに結果が返ってくるまで、ほかの処理を行わずに待機します。

非同期では、結果が返ってくるまでの間にほかの処理ができ、結果が返ってきた時点でレスポンスの受信処理を実行します。同期型の場合、お互いを確認し合ったうえでやりとり行うため、相手から応答がないと待たされることになります。非同期でデータをやりとりするには、最近ではAjax技術が有名ですが、もともとJava Appletでも可能です。

同期/非同期を人と人の“会話”に例えてみることにしましょう。例えば、先生が生徒であるA君に「放課後先生のところに来るように」伝えようとした場合、以下のようなやりとりになります。

図3 返事を待つ 図3 返事を待つ

ところが、次のように先生が待たされてしまうこともあります。

図4 返事がない…… 図4 返事がない……

では、非同期型の場合はどうでしょうか。非同期では相手に伝わったかどうか確実でなくても、要求することになります。

例えば、校内放送で「3年1組のA君、放課後職員室に来てください」というような伝え方です。この場合、A君に確実に伝わったかどうかは分かりませんが、先生は職員室でA君が来るまでテストの採点など別の仕事ができます。A君が職員室に来たら、話を始めればよいわけです。


Webブラウザはなぜステート(状態)を保持しないのか?

 「ステートとは何か?」を簡単に説明すると、処理を実行した結果(状態)のことを指します。

図5 ステートとは? 図5 ステートとは?

 もともと、Webブラウザはステートを保持するという発想を持っていません。Webサイトにアクセスする際にはHTTPプロトコルを通してデータを要求し、データを受信したところで一連の流れ(セッション)が完了します。ですがこれでは、Web上で複雑な処理をできないため、Cookie(クッキー)、セッションを利用した保持、つまりステートの保持が行われるようになったのです。

ステートレス/フルとは、どんな“状態”?

 ステートを利用したサーバには、ステートフルとステートレスに分かれます。

  • ステートフル
    誰からのリクエストかを判断して状態を保持できる状態
  • ステートレス
    レスポンスを返すごとに処理が完結することで、どこにも状態を保持しない

 ステートフルでは、2回目以降の処理では、それまでの情報は繰り返さなくてもよいのです。それは、サーバがクライアントのステートを保持しているからです。それにより、次の処理を実行した際は、サーバは保持しているステートを追加・編集してあらためて更新します。

ステートフルの方がよい?

 普通に考えて、ステートフルが理にかなっているように見えますが、1人のクライアントをずっと相手にしていると、その間、別のクライアントに対応できません。よって、アクセスが集中する場合は、Webサーバを増設して対応することになります。

 ここで、ステートレスであれば、各インタラクションで別々のサーバがクライアントのリクエストに応答可能になります。スケーラビリティの観点から見ると、ステートレスの方が理にかなっているといえます。

 ですが、各インタラクションで別々のサーバが必要になるということは「インタラクションが増える=サーバが増える」ということになります。では、一般的なWebサーバはどのように対策しているのでしょうか?

 実は、一般的なWebサーバは「ステートレス」ですが、先ほど説明したセッション、Cookieの仕組みを併用することで「ステートフル」を疑似的に実現しているのです。次ページでは、その例を示します。

コラム 「スクリプティング変数とスコープ」

ステートを保持する仕組みとしてスクリプティング変数と、そのスコープ(scope、範囲)もあります。スクリプティング変数は、JSPなどのWebアプリケーションで保持したい情報を格納するオブジェクトですが、その保持する範囲は以下になります。

JSPは上記の4つのスコープしかありませんが、Webアプリケーション・フレームワークのJBoss Seamでは、以下のように7つもスコープがあります。

もちろんスコープは、Strutsにも関係します。後ほど登場するstruts-config.xmlの<action>タグのscope属性にも注目してみてください。


Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。