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


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

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

### ソースコード

#### マッピング

```xml
<!-- 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>
```

#### アクションフォーム

```java
// 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ページ

##### 入力画面

```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>&lt;%=request.getRequestURI()%&gt;</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>
```

##### リクエストスコープの確認画面

```jsp
<%-- 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>&lt;%=request.getRequestURI()%&gt;</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>&lt;%=request.getRequestURI()%&gt;</h1>
<h3>html:formでアクションフォームに値を渡す</h3>
<p>フォームで入力したテキスト:<bean:write name="inputForm" property="text"></bean:write></p>

</html:base></html:html>
```

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

htmlフォームで日本語を入力して  
![struts_01_141007.jpg](https://qiita-image-store.s3.amazonaws.com/0/62881/d48d5a28-dfa4-1c69-2402-ac65998abc16.jpeg "struts_01_141007.jpg")


アクションフォームを通して、htmlフォーム値が返ってきていることを確認。そのまま下記のリンクをクリックして、別リクエストを要求。別のJSPページへ移動します。  
![struts_02_141007.jpg](https://qiita-image-store.s3.amazonaws.com/0/62881/984b2d53-1da7-54c1-350a-a5cacb351609.jpeg "struts_02_141007.jpg")


このリクエストではJSPにフォワードされるだけで、アクションクラスは実行されません。struts-config.xmlでaction要素にname属性も設定していないため、値を渡すという処理はしていません。それにもかかわらず値が渡ってきているので、Struts1.3.10のアクションフォームのスコープはセッションであることがわかりました。  
![struts_03_141007.jpg](https://qiita-image-store.s3.amazonaws.com/0/62881/a73fb1d9-1765-8ec8-1504-0a21105a8580.jpeg "struts_03_141007.jpg")



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

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

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

もう一度入力画面にアクセスすると、今度は初期値が先ほどの「あいうえお」になっています。まだ何も入力はしていません。どうやら、
`<html:text>`には入力値が残るみたいです。これが嫌な場合はどこかで明示的に空文字をアクションフォームに入れないといけません。  
![struts_04_141007.jpg](https://qiita-image-store.s3.amazonaws.com/0/62881/cddc70f6-1bac-440c-21c6-a5788d5fdb53.jpeg "struts_04_141007.jpg")



とりあえず、「リクエスト」と文字を入力して送信します。スコープがリクエストなので下記の画面までは値が渡ります。  
![struts_05_141007.jpg](https://qiita-image-store.s3.amazonaws.com/0/62881/53d4f1e6-2594-2ad2-e142-d5f628562301.jpeg "struts_05_141007.jpg")


では、もう一度リンクをクリックしてみましょう。  
![struts_06_141007.jpg](https://qiita-image-store.s3.amazonaws.com/0/62881/5ffbfdcd-c427-6fa9-38f8-69a9ff0225a8.jpeg "struts_06_141007.jpg")

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