Struts1のアクションフォームの寿命はいつまでなのか調べる

~.doにアクセスしてJSPページが返ってきて1つのHTTPリクエストが終了です。また違うURLにアクセスした際は別のHTTPリクエストとして扱われます。つまり、変数のスコープがリクエストだと、この時点で破棄されてしまいます。他のページに移動後にも変数を維持したい場合は、セッションを使います。

さて、Srtutsのアクションフォームは、デフォルトではどこまで維持されるのでしょうか。下記のプロジェクトファイルで実験してみました。

ソースコード

マッピング

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!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-beans>
        <form-bean name="inputForm" type="InputForm" />
    </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-mappings>
</struts-config>

アクションフォーム

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ページ

入力画面
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<html:html>
<head>
<html:base/>
</head>
<body>
<h1><%=request.getRequestURI()%></h1>
<h3>html:formでアクションフォームに値を渡す</h3>
<html:form action="/RequestOutput.do">
    <html:text property="text" />
    <html:submit />
</html:form>
</body>
</html:html>
 リクエストスコープの確認画面
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<html:html>
<head>
<html:base/>
</head>
<body>
<h1><%=request.getRequestURI()%></h1>
<h3>html:formでアクションフォームに値を渡す</h3>
<p>フォームで入力したテキスト:<bean:write name="inputForm" property="text"/></p>
<p><a href="/struts-blank-1.3.10/SessionOutput.do">アクションフォームが次のHTTPリクエストでも引き継がれるか調べる</a></p>
</body>
</html:html>
セッションスコープの確認
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<html:html>
<head>
<html:base/>
</head>
<body>
<h1><%=request.getRequestURI()%></h1>
<h3>html:formでアクションフォームに値を渡す</h3>
<p>フォームで入力したテキスト:<bean:write name="inputForm" property="text"/></p>
</body>
</html:html>

デフォルトのスコープを確かめる

htmlフォームで日本語を入力してstruts_01_141007

アクションフォームを通して、htmlフォーム値が返ってきていることを確認。そのまま下記のリンクをクリックして、別リクエストを要求。別のJSPページへ移動します。struts_02_141007

このリクエストではJSPにフォワードされるだけで、アクションクラスは実行されません。struts-config.xmlでaction要素にname属性も設定していないため、値を渡すという処理はしていません。それにもかかわらず値が渡ってきているので、Struts1.3.10のアクションフォームのスコープはセッションであることがわかりました。

struts_03_141007

明示的にアクションフォームのスコープをリクエストにする

struts-config.xmlでscope属性を明示的に設定しましょう。設定後はtomcatを再起動します。

<!-- リクエストスコープを確かめる -->
        <action path="/RequestOutput" name="inputForm" forward="/pages/RequestOutput.jsp"
            scope="request" />

もう一度入力画面にアクセスすると、今度は初期値が先ほどの「あいうえお」になっています。まだ何も入力はしていません。どうやら、<html:text />には入力値が残るみたいです。これが嫌な場合はどこかで明示的に空文字をアクションフォームに入れないといけません。

struts_04_141007

とりあえず、「リクエスト」と文字を入力して送信します。スコープがリクエストなので下記の画面までは値が渡ります。

struts_05_141007

では、もう一度リンクをクリックしてみましょう。

struts_06_141007

値が変わっていますね。これは前に入力した値がセッションに保存されていたので、それが出力されています。今入力したのはスコープがリクエストのため、もう破棄されていることがわかります。