課題 (07:ウェブアプリケーション)

作業について

今回の課題は以下のパッケージに作成してください。

パッケージの名前
j1.lesson07

作成するクラスの名前は問題ごとに指示があります。下記を参照してください。

課題の提出方法については下記を参照してください。

また、別のコンピューター上に移動する際には、下記を参考にプログラムを持ち帰ってください。

新しい内容

セッション

Webアプリケーションは、リクエスト/レスポンスが連続して動作することで画面が遷移していました。図は、この様子を示したものです。(1)の通信で(2)の処理がサーバーで行われています。サーバーの処理はこれで完結するため、ここで利用したデータや計算した値などは、処理が完了した時点ですべて消えてしまいます。(3)の通信も同様です。つまり、(4)の処理は(2)の処理とまったく独立しており、(4)からは(2)の計算結果などを見ることは出ません。(1)の通信が終了した時点(レスポンスがクライアントに返った時点)で、(2)の情報は消えているからです。

図 セッションを利用しない場合

この仕組は、Webアプリケーションの通信(HTTPプロトコル)の大きな特徴のひとつです。さて、ここで困った問題が起こります。ショッピングサイトを例に説明します。ショッピングサイトでは、商品をカートに保存してゆき、まとめて決済することができます。カートに保存する処理を、図1の(1)と(2)で行ったとします。続けて決済を、(3)と(4)で行おうとしますが、(4)ではカートの内容を見ることができません。(2)でカートに商品をいれたとしても、カートそのものが消えてしまうからです。この仕組のままでは、ショッピングサイトを作ることができないということになります。

セッションの仕組み

セッションという入れ物を利用することで、ショッピングサイトの問題を解決することができます。図は、セッションを利用した場合の動作の流れを示しています。


図 セッションを使ってデータを引き継ぐ

(2)の処理で保存したい情報をセッションに格納しています。(4)の処理では、セッションから必要な情報をとりだしています。セッションを利用した仕組で、ショッピングサイトを作るとどうなるでしょうか。カートに保存する処理は、図2の(2)で行います。カートそのものをセッションに格納します。(4)では、セッションからカートをとりだし、カートに保存されている商品を参照して決済の処理を行うことができます。セッションの仕組みは、サーバーでデータを保存する入れ物を用意すればよく、一見単純な解決策にみえます。実際、セッションを利用するプログラムはそれほど複雑にはなりません。セッションの入れ物はWebアプリケーションサーバーが用意しています。クライアントが異なれば自動的に別のセッションの入れ物を用意します。そのため、自分のセッション情報は他人からは見えないことになります。

プログラムでセッションを利用する

プログラムからセッションを利用する方法を以下に説明します。

セッションにデータを記憶させるには、次のように書きます。

WebPage.setSession([保存名], [記憶させる値]);

保存名を文字列で指定して、記憶させる値をセッションに格納します。なお、数値や文字列、今週習った配列などもそのまま記憶させられます。

セッションにデータが記憶されているかどうかを調べるには、次のように書きます。

if (WebPage.hasSession([保存名])) {
    … セッションにデータが記憶されている場合の処理
}
else {
    … セッションにデータが記憶されていない場合の処理
}

保存名を文字列で指定して、オブジェクトをセッションに格納します。

セッションからのデータの取得は、次のように書きます。

int intValue = WebPage.getSession([保存名]);
double doubleValue = WebPage.getSession([保存名]);
String stringValue = WebPage.getSession([保存名]);

保存名をもとに、記憶させたデータを取得します。セッションの保存名に該当するデータがなかった場合はエラーになります。なお、上記のほかに配列などのデータも取り出せます。

セッションの利用例

以下はセッションを利用したプログラムの例です。

package j1.lesson07;

import gpjava.WebPage;

public class SessionExample {

    public static void main(String[] args) {
        new SessionExample().start();
    }

    void start() {
        WebPage.open("セッションのサンプル");
        if (!WebPage.hasSession("visit-count")) {
            WebPage.paragraph("初めての訪問です");
            WebPage.setSession("visit-count", 1);
        }
        else {
            int count = WebPage.getSession("visit-count");
            WebPage.paragraph((count + 1) + "回目の訪問です");
            WebPage.setSession("visit-count", count + 1);
        }
    }
}

このプログラム ( http://localhost:8888/j1.lesson07/SessionExample ) では、まず "visit-count" という名前のデータがセッションに記憶されているか調べています。

セッションに記憶されていない場合には、「初めての訪問です」と表示したうえで、セッションに「1」という値を記憶させます。この値は、「これまでにこのページを訪問した回数」を表しています。

セッションに記憶されている場合には、この訪問回数をセッションから取り出して「(訪問回数+1)回目の訪問です」と表示して、さらにセッションに表示した値を記憶させています。

ウェブページで見かける訪問回数を表す「カウンタ」は、基本的には似たような仕組みで作られています (最近はあまり見かけなくなりました)。このセッションの仕組みを利用すると、利用者の情報をもとにしたアプリケーションを作成できます。

問題

今回は簡単なショッピングカートを作成します。

a. カートに追加する商品を入力する

作成するクラスの名前
ItemInput
動作を確認するためのURL
http://localhost:8888/j1.lesson07/ItemInput

商品の名前と価格を入力するフォームを作成してください。

フォームの送信先は、次に作成する「CartView」として、送信ボタンも配置してください。

b. これまでに追加された商品を表示する

作成するクラスの名前
CartView

ItemInputから追加された商品と価格を表示する、次のようなテーブルを表示して下さい。

商品名 価格
(入力した商品名) (入力した価格)

さらに http://localhost:8888/j1.lesson07/ItemInput に戻って再度商品名と価格を入力した際には、テーブルの末尾に入力した商品名と価格を表示して下さい。

たとえば、上記の操作を5回行った場合、次のようなテーブルを表示します。

商品名 価格
(1回目に入力した商品名) (1回目に入力した価格)
(2回目に入力した商品名) (2回目に入力した価格)
(3回目に入力した商品名) (3回目に入力した価格)
(4回目に入力した商品名) (4回目に入力した価格)
(5回目に入力した商品名) (5回目に入力した価格)

ヒント

セッションに商品名や価格があることを確認するには、「WebPage.hasSession()」メソッドを使います。

セッションに保存されていない場合には、次のような処理が必要です。

  • 長さ1の配列を作成する
  • 入力された情報を配列に記憶させる
  • 配列をセッションに保存する

セッションに保存されている場合には、次のような処理が必要です。

  • セッションから配列を取り出す
  • 取り出した配列より長さが1つ大きな新しい配列を作成する
  • 新しい配列に、取り出した配列の内容をコピーする
  • 新しい配列の末尾に、入力された情報を記憶させる
  • 配列をセッションに保存する

ヒント

下記のメソッドは、「配列arrayの末尾にvalueを追加した配列を作成して返す」ようなメソッドです。

int[] append(int[] array, int value) {
    int[] newArray = new int[array.length + 1];
    for (int i = 0; i < array.length; i++) {
        newArray[i] = array[i];
    }
    newArray[array.length] = value;
    return newArray;
}

c. 合計金額を表示する

さらに、テーブルの末尾に合計金額を表示するようにしてください。

商品名 価格
(1回目に入力した商品名) (1回目に入力した価格)
(2回目に入力した商品名) (2回目に入力した価格)
(3回目に入力した商品名) (3回目に入力した価格)
(4回目に入力した商品名) (4回目に入力した価格)
(5回目に入力した商品名) (5回目に入力した価格)
合計 (1回目から5回目までの価格の合計)