~.do
にアクセスしてJSPページが返ってきて1つのHTTPリクエストが終了です。また違うURLにアクセスした際は別のHTTPリクエストとして扱われます。つまり、変数のスコープがリクエストだと、この時点で破棄されてしまいます。他のページに移動後にも変数を維持したい場合は、セッションを使います。
さて、Srtutsのアクションフォームは、デフォルトではどこまで維持されるのでしょうか。下記のプロジェクトファイルで実験してみました。
ソースコード
マッピング
<!-- struts-config.xml -->
<?xml version="1.0" encoding="ISO-8859-1" ?>
<struts-config>
<form-beans>
<form-bean name="inputForm" type="InputForm">
</form-bean></form-beans>
<action-mappings>
<!-- 入力画面 -->
<action path="/Input" name="inputForm" forward="/pages/Input.jsp">
<!-- リクエストスコープを確かめる -->
<action path="/RequestOutput" name="inputForm" forward="/pages/RequestOutput.jsp">
<!-- セッションスコープを確かめる -->
<action path="/SessionOutput" forward="/pages/SessionOutput.jsp">
</action></action></action></action-mappings>
</struts-config>
アクションフォーム
// InputForm.java
import java.io.UnsupportedEncodingException;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
public class InputForm extends ActionForm {
private String text;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
@Override
public void reset(ActionMapping mapping, HttpServletRequest request) {
try {
request.setCharacterEncoding("utf-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
resetメソッドはアクションフォームが呼び出されるときに必ず実行されるメソッドです。ここでHTMLフォームから受けとった値をJSPに渡すときにUTF-8でエンコーディングしています。JSPでcharsetをUTF-8にするだけだと、JSPに記述した日本語は文字化けをしませんが、アクションフォームから受けとった値は文字コードが違うため文字化けしてしまいます。
JSPページ
入力画面
<%-- Input.jsp %-->
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<html:html>
<html:base>
<h1><%=request.getRequestURI()%></h1>
<h3>html:formでアクションフォームに値を渡す</h3>
<html:form action="/RequestOutput.do">
<html:text property="text">
<html:submit>
</html:submit></html:text></html:form>
</html:base></html:html>
リクエストスコープの確認画面
<%-- RequestOutput.jsp %-->
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<html:html>
<html:base>
<h1><%=request.getRequestURI()%></h1>
<h3>html:formでアクションフォームに値を渡す</h3>
<p>フォームで入力したテキスト:<bean:write name="inputForm" property="text"></bean:write></p>
<p><a href="/struts-blank-1.3.10/SessionOutput.do">アクションフォームが次のHTTPリクエストでも引き継がれるか調べる</a></p>
</html:base></html:html>
セッションスコープの確認
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<html:html>
<html:base>
<h1><%=request.getRequestURI()%></h1>
<h3>html:formでアクションフォームに値を渡す</h3>
<p>フォームで入力したテキスト:<bean:write name="inputForm" property="text"></bean:write></p>
</html:base></html:html>
デフォルトのスコープを確かめる
アクションフォームを通して、htmlフォーム値が返ってきていることを確認。そのまま下記のリンクをクリックして、別リクエストを要求。別のJSPページへ移動します。
このリクエストではJSPにフォワードされるだけで、アクションクラスは実行されません。struts-config.xmlでaction要素にname属性も設定していないため、値を渡すという処理はしていません。それにもかかわらず値が渡ってきているので、Struts1.3.10のアクションフォームのスコープはセッションであることがわかりました。
明示的にアクションフォームのスコープをリクエストにする
struts-config.xmlでscope属性を明示的に設定しましょう。設定後はtomcatを再起動します。
<!-- struts-config.xml -->
<!-- リクエストスコープを確かめる -->
<action path="/RequestOutput" name="inputForm" forward="/pages/RequestOutput.jsp"
scope="request" />
もう一度入力画面にアクセスすると、今度は初期値が先ほどの「あいうえお」になっています。まだ何も入力はしていません。どうやら、
<html:text>
には入力値が残るみたいです。これが嫌な場合はどこかで明示的に空文字をアクションフォームに入れないといけません。
とりあえず、「リクエスト」と文字を入力して送信します。スコープがリクエストなので下記の画面までは値が渡ります。
値が変わっていますね。これは前に入力した値がセッションに保存されていたので、それが出力されています。今入力したのはスコープがリクエストのため、もう破棄されていることがわかります。