それでは、「ステートフル」を疑似的に実現している簡単なプログラムを作成して確認してみましょう。まず、「PKG\Hello\pages」配下に、下記のJSPファイルを作成してください。
State01.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" %>
<html:html>
<head><title>Session/Cookieサンプル(入力画面)</title></head>
<html:form action="/State">
<table border="0">
<bean:include id="top" page="/pages/Header.jsp" />
<tr><td><%=top %></td></tr>
<tr><td>
名前 :
<html:text property="name" size="10" maxlength="5" />
</td></tr><tr><td>
メールアドレス :
<html:text property="address" size="30" maxlength="30" />
</td></tr><tr><td>
年齢 :
<html:text property="age" size="4" maxlength="3" />
</td></tr><tr><td>
<html:submit property="submit">
<bean:message key="button.next" />
</html:submit>
</td></tr>
</table>
</html:form>
</html:html> |
|
State02.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" %>
<html:html>
<head><title>Session/Cookieサンプル(確認画面)</title></head>
<html:form action="/State02">
<table border="0">
<bean:include id="top" page="/pages/Header.jsp" />
<tr><td><%=top %></td></tr>
<tr><td>
名前 :
<bean:write name="StateForm" property="name" />
</td></tr><tr><td>
メールアドレス :
<bean:write name="StateForm" property="address" />
</td></tr><tr><td>
年齢 :
<bean:write name="StateForm" property="age" />
</td></tr><tr><td>
<html:submit property="submit">
<bean:message key="button.start" />
</html:submit>
</td></tr>
</table>
</html:form>
</html:html> |
|
State03.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" %>
<html:html>
<head><title>Session/Cookieサンプル(結果画面)</title></head>
<html:form action="/State02">
<table border="0">
<bean:include id="top" page="/pages/Header.jsp" />
<tr><td><%=top %></td></tr>
<tr><td>
名前 :
<bean:write name="StateForm" property="name" />
</td></tr><tr><td>
メールアドレス :
<bean:write name="StateForm" property="address" />
</td></tr><tr><td>
年齢 :
<bean:write name="StateForm" property="age" />
</td></tr>
</table>
</html:form>
</html:html> |
|
Header.jsp |
<%@ page contentType="text/html; charset=Shift_JIS" %>
<h1>Sessionサンプル</h1> |
|
次に、Javaパッケージを作成します。Eclipseから「Hello」プロジェクトの[ソース・フォルダー](「WEB-INF/src」)で右クリックして、新規の[Java パッケージ]を選択します。
図6 新規[Java パッケージ]
[ソース・フォルダー]で「Hello/WEB-INF/src」を参照し、[名前]で「state」と入力して[終了]ボタンを選択します。同様の操作で「state.form」パッケージも作成します。これで、新規のJavaパッケージの作成は完了です。Javaパッケージを作成したら、「state.form」パッケージ配下に以下の.javaファイル(StateForm.java)を作成します。
StateForm.java |
package state.form;
import org.apache.struts.action.ActionForm;
public class StateForm extends ActionForm {
private String name;
private String address;
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
} |
|
「state」パッケージ配下に、以下の.javaファイル(State01Action.java、State02Action.java)と.propertiesファイル(State_ja.properties)を作成します。
State01Action.java |
package state;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import state.form.StateForm;
public class State01Action extends Action {
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
HttpSession session = request.getSession(true);
StateForm stateForm = (StateForm) form;
session.setAttribute("StateForm", stateForm);
return mapping.findForward("success");
}
} |
|
State02Action.java |
package state;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
public class State02Action extends Action {
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
return mapping.findForward("success");
}
} |
|
State_ja.properties |
button.next=NEXT
button.start=END |
|
最後に、WEB-INFフォルダのstruts-config.xmlを以下の内容に編集します。
<?xml version="1.0" encoding="Shift-JIS" ?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
"http://struts.apache.org/dtds/struts-config_1_3.dtd">
<struts-config>
<!-- ========================= Form Bean Definitions -->
<form-beans>
……【省略】……
<!-- ここから -->
<form-bean name="StateForm" type="state.form.StateForm" />
<!-- ここまで追加 -->
</form-beans>
……【省略】……
<!-- ========================= Action Mapping Definitions -->
<action attribute="HelloForm" input="/pages/Parameter.jsp"
name="HelloForm" path="/Request"
type="request.RequestAction"
scope="session"
validate="true">
<forward name="success" path="/pages/Request.jsp" />
</action>
<!-- ここから -->
<action
attribute="StateForm"
input="/pages/State01.jsp"
name="StateForm"
path="/State"
type="state.State01Action"
scope="session"
validate="true">
<forward name="success" path="/pages/State02.jsp" />
</action>
<action
attribute="StateForm"
input="/pages/State02.jsp"
name="StateForm"
path="/State02"
type="state.State02Action"
scope="session"
validate="true">
<forward name="success" path="/pages/State03.jsp" />
</action>
<!-- ここまで追加 -->
<!-- ========================== Message Resources Definitions -->
<!-- ここから -->
<message-resources parameter="state.State"/>
<!-- ここまで追加 -->
<!-- ========================== Plug Ins Configuration -->
<!-- ========================== Tiles plugin -->
<!-- ========================== Validator plugin -->
</struts-config> |
これで、サンプルプログラムの作成は完了です。Eclipseで[プロジェクト]の[クリーン]を選択してHelloプロジェクトをコンパイルします。
コンパイルが終わったら、Eclipse上から「Tomcat起動」アイコン(猫マーク)を押して、起動してみてください。コンソールが何やら動き出しましたね。早速確認してみましょう。WebブラウザからURL「http://localhost:8080/hello/pages/State01.jsp」を参照してみてください。すると、下記の画面が表示されたかと思います。
図7 入力画面
入力画面に、「名前」「メールアドレス」「年齢」を入力して「NEXT」ボタンを押してください。すると、下記のような画面が表示されると思います。これは、入力画面(State01.jsp)で入力した情報(StateForm)をState01Action.javaでセッションにセットし、出力しています。
図8 確認画面
それでは、「END」ボタンを押してみてください。すると、下記の画面が表示されます。
図9 結果画面
一見、前の画面と変わっていないと思いますが、「END」ボタンを押した際の処理はState02Action.javaを実行しています。
State02Action.javaでは、画面の遷移の処理です。しかし、State01Action.javaの処理の際、セットされたセッションの情報を保持したままの状態のため、State02Action.javaを経由しても同じ情報を出力することが可能なのです。
このようにセッションやCookieを利用することで、「ステートフル」を疑似的に実現しているWebアプリケーションを実現できます。
<bean:message>タグはメッセージリソースからメッセージを読み込みます。今回は入力画面のボタン「NEXT」の値や「END」の値を定義ファイル(State_ja.properties)の情報を取り出し、属性「key」で指定して出力しています。
<bean:include>タグはほかのページを動的に読み込むためのものです。<jsp:include>と同様の使い方です。今回は、ヘッダー部分(Header.jsp)を動的に読み込んでいます。ヘッダー部分を共通で使用する場合、この仕組みを使えば1つのJSPを編集するだけで済みます。
このように、今回はセッションやCookieの仕組みを利用したWebアプリケーションにおけるステートについて説明しましたが、いかがでしたでしょうか。[戻る]ボタンや2度押し、[F5]キー連打の問題の根底にあるものが理解できたかと思います。Webアプリケーション開発にぜひ生かしていただければ幸いです。
次回は、Webアプリケーションにおけるバリデーションやテンプレートエンジンについて説明していきたいと思います。
今回のサンプルは、こちらからダウンロードできます。
眞野 寿彦(まの としひこ)
株式会社メセナ・ネットコム所属
SEとして充実した日々を送っている。現在はStrutsを使ったWebアプリケーション開発を担当中。「信頼されるプロジェクトマネジャー」を目指し、自分に必要なことを常に考え、行動し、「真の技術者」として日々成長している。
趣味はボウリング、ビリヤード、ダーツ
尊敬する人はティム・バーナーズ=リー