前提
JSPの入門を勉強済み。
Struts2を動かす環境構築済み。
Struts2でHelloWorldレベルのコードを写生したことがある。
プロジェクトツリー構造
web.xml
丸ごとコピーでいい。
welcome-file-listタグの中はindexページの優先順位を書いているだけ
filterタグの中はどのページにstruts2フレームワークを適用するかを指定している。
この場合 /* だから全部のディレクトリ。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>Struts2Calc</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
struts.xml
ルーティングを書くファイル。
packageタグはこのタグ自体の拡張に使用されるらしい。
この場合、struts-defaultというpackageタグが他に定義されていてそれを継承します。ということのようです。
今回はこれ以上継承しませんが、他のpackageタグから継承したくなった時にはこのname属性の値をキーにして継承するようです。
actionタグの中、
name=このactionの識別子になる。jsp内の<s:form action="値">で指定した値と一致させることで呼べる。
class=起動するJavaのActionクラス。今回はcontrollerパッケージのCalcAction.javaを指定している。
method=上のJavaクラス内のどのメソッドを動かすかを指定。Actionクラス側でimplemetnsするクラスに
executeの関数名でのoverrideを求められる場合があるので、特に理由がなければexecuteを指定しておくと良さそう。
resultタグの中
name=上記のクラスのexecute関数(名前変えてたらそれ)で、returnされた名前
index.jsp=name属性に対応する結果がリターンされた時の遷移先を指定。今回はindex.jspだが実際に合わせて変える。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="default" extends="struts-default">
<action name="calc" class="controller.CalcAction" method="execute">
<result name="success">/index.jsp</result>
</action>
</package>
</struts>
CalcFormBean
jsp内のformタグ内で使用するtextboxの値を格納するためのモデルクラス。
この内容はActionクラスに直に書いても動きます。が、それだとこういう練習アプリならともかく、実戦で大きなアプリを書く時に
Actionクラスがとてつもなく肥大化するので切り離すべきでしょう。
POJOクラスだけど、Serializableをimplementsしておかないとsessionとかに保存できないので、
基本的につけといた方がいいでしょう。
package bean;
import java.io.Serializable;
public class CalcFormBean implements Serializable {
private String text1;
private String text2;
public String getText1() {
return text1;
}
public void setText1(String text1) {
this.text1 = text1;
}
public String getText2() {
return text2;
}
public void setText2(String text2) {
this.text2 = text2;
}
public String getSum() {
int x = Integer.parseInt(this.text1);
int y = Integer.parseInt(this.text2);
Integer sum = x + y;
return sum.toString();
}
public String getSubtract() {
int x = Integer.parseInt(this.text1);
int y = Integer.parseInt(this.text2);
Integer sum = x - y;
return sum.toString();
}
}
CalcAction
private CalcFormBean bean;
で上記のフォームビーンを定義しています。
newがどこにもありませんが、これだけでインスタンス化されています。
getter/setterの命名規則でインスタンスが生まれるので、カプセル化せずにpublic変数に
するとかではダメです。
String execute()は上記のstruts.xmlで指定したメソッド名。
今回ActionSupportというのをextendsしており、この場合execute()をoverrideすることになります。
実はこのアプリでは何もextendsしなくても動きます。
つけている入門ページが多いのでなんとなく習ってつけてみてるだけです。
まだよくわかっていないので。
package controller;
import com.opensymphony.xwork2.ActionSupport;
import bean.CalcFormBean;
public class CalcAction extends ActionSupport{
private CalcFormBean bean;
public String execute() {
return "success";
}
public CalcFormBean getBean() {
return bean;
}
public void setBean(CalcFormBean bean) {
this.bean = bean;
}
}
index.jsp
今回はこのページしか使いません。
submitした時の画面遷移先をこのページにしているため、サーバで計算した後ここに戻ってきます。
<%@ taglib prefix="s" uri="/struts-tags"%>でstrutsタグをロード。
<s:textfield name="bean.text1">でActionクラスに定義したsetterを呼び出しています。
setBean()で書き込む先のCalcFormBean.javaにはtext1とtext2が定義されているのでjavaSEのような書き方で
セットできます。
<s:property value="bean.text1">はその逆でプロパティから値を取り出して表示します。
<s:if test="bean.subtract<0">は条件がtrueの時だけifタグの中を表示します。
test=""の中が条件式になっていて、bean.subtract(ここでは引き算の結果が格納されている)
が0未満の場合に赤字で「マイナスです。」を表示させています。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Struts入門</title>
</head>
<body>
<h1>計算機</h1>
<s:form action="calc">
<s:textfield name="bean.text1" label="値1"/><br>
<s:textfield name="bean.text2" label="値2"/>
<s:submit value="計算実行"/>
</s:form>
<s:property value="bean.text1"/>+<s:property value="bean.text2"/>=<s:property value="bean.sum"/> <br>
<s:property value="bean.text1"/>-<s:property value="bean.text2"/>=<s:property value="bean.subtract"/>
<s:if test="bean.subtract<0">
<p style="color:red">マイナスです。</p>
</s:if>
</body>
</html>