struts2でのMaven活用方法
1.pom.xml例
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelversion>4.0.0</modelVersion> <groupid>com.example.webchat2</groupId> <artifactid>webchat2</artifactId> <packaging>war</packaging> <version>1.0</version> <name>webchat2 Maven Webapp</name> <dependencies> <dependency> <groupid>junit</groupId> <artifactid>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupid>org.apache.tomcat</groupId> <artifactid>servlet-api</artifactId> <version>6.0.35</version> <scope>provided</scope> </dependency> <dependency> <groupid>org.apache.struts</groupId> <artifactid>struts2-core</artifactId> <version>2.3.1.2</version> </dependency> <dependency> <groupid>org.apache.struts</groupId> <artifactid>struts2-convention-plugin</artifactId> <version>2.3.1.2</version> </dependency> </dependencies> <build> <finalname>webchat2</finalName> <plugins> <plugin> <groupid>org.apache.maven.plugins</groupId> <artifactid>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> </plugins> </build> </project>
web.xml
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>webchat2</display-name> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
Struts2のオフィシャルドキュメントで
http://struts.apache.org/2.3.1.2/docs/webxml.html
Changed Filter Structure in Struts >= 2.1.3To split up the the dispatcher phases, FilterDispatcher is deprecated since Struts 2.1.3. If working with older versions, you need to use
... <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> ...
(後略)
※上記の意訳
Struts2.1.3以降のFilter構成の変更
dispathcerフェーズを分割するために、Struts2.1.3からFilterDispatcherは非推奨になったぜ!もし古いバージョンで動かしたい場合は下にあるとおりにしてな!
おおう…。結構ネットのサンプルが2.1.3より前のものが多いなぁ。
ということでFilterは「org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter」を使っております。
1.javaクラス作成
※techscoreのサンプルにある、MessageBean、MessageDao、MessageDaoOnMemoryImplはそのまま使います。
ShowMessages.java
package com.example.webchat2.webapp.struts2; import com.example.webchat.db.bean.MessageBean; import com.example.webchat.db.dao.MessageDao; import com.example.webchat.db.dao.impl.MessageDaoOnMemoryImpl; import com.opensymphony.xwork2.Action; public class ShowMessages implements Action{ public MessageBean[] messages; public String name; public String execute() throws Exception { MessageDao messageDao = MessageDaoOnMemoryImpl.getInstance(); messages = messageDao.getAll(); return "success"; } }
SaveMessage.java
package com.example.webchat2.webapp.struts2; import java.util.Date; import com.example.webchat.db.bean.MessageBean; import com.example.webchat.db.dao.MessageDao; import com.example.webchat.db.dao.impl.MessageDaoOnMemoryImpl; import com.opensymphony.xwork2.Action; import org.apache.struts2.convention.annotation.Result; @Result(name="success", type="redirect", location="/show-messages") public class SaveMessage implements Action{ public String name; public String message; public String execute() throws Exception { Date date = new Date(); MessageDao messageDao = MessageDaoOnMemoryImpl.getInstance(); messageDao.save(new MessageBean(date, name, message)); message = ""; return "success"; } }
今回はstruts.xmlを使わずにstruts2がURIから自動で呼出しクラスを考えてくれる機能(Zero Configurationというらしい)を活用することにしました。
そのため、
- クラスは、「”Action”で終わるクラス名のクラス」「com.opensymphony.xwork2.Actionの継承しているクラス(間接継承OKぽい)」であること。
- クラスのパッケージにstruts,struts2,action,actionsのいずれかを含める。
今回は「com.example.webchat2.webapp.struts2」 - 含めたキー(今回は「struts2」)の直下にクラスを配置する。
(さらにパッケージを掘り下げてAction役のクラスを配置するとネームスペースとして掘り下げたパッケージ名が使われるらしい。詳細はgoogle先生へ…)
としました。
2.JSP作成
show-messages.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags" %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>webChat</title> </head> <body> <h1>WebChat</h1> <hr/> <h2>発言フォーム</h2> <s:form action="/save-message"> <s:textfield name="name" label="名前" style="width:256" /> <s:textfield name="message" label="メッセージ" style="width:256" /> <s:reset value="リセット" /><s:submit value="送信" /> </s:form> <hr /> <h2>メッセージ</h2> <s:form action="/show-messages"> <s:submit value="更新" /> </s:form> <table border="1" cellspacing="0" cellpadding="3"> <tr><th>日付</th><th>名前</th><th>メッセージ</th></tr> <s:iterator var="message" value="messages"> <tr> <td><s:date name="date" format="yyyy/MM/dd hh:mm:ss.SSS"/></td> <td><s:property value="name"/></td> <td><s:property value="message"/></td> </tr> </s:iterator> </table> </body> </html>
基本的にtagはstruts2のものに変更しました。textfieldやsubmitはHTMLになったときにtableタグなどを自動で出力していまいますが、今回は練習ということでそのまま使っています。あとは、techscoreのサンプルでは「更新」がリンクだったのですが、taglibのaでは上手くActionとマッピングされない(やり方あると思うけど探してない…)ようだったので、formとsubmitを使っています。
また、Dateクラスをpropertyで出力すると日付しか出力されなかったため、dateタグとformat属性を使って出力形式を指定しました。
3.package展開
ここで
mvn package
を実行するとこんな構成になります。(たぶん)
. ├── pom.xml ├── src │ └── main │ ├── java │ │ └── com │ │ └── example │ │ ├── webchat │ │ │ └── db │ │ │ ├── bean │ │ │ │ └── MessageBean.java │ │ │ └── dao │ │ │ ├── MessageDao.java │ │ │ └── impl │ │ │ └── MessageDaoOnMemoryImpl.java │ │ └── webchat2 │ │ └── webapp │ │ └── struts2 │ │ ├── SaveMessage.java │ │ └── ShowMessages.java │ ├── resources │ └── webapp │ ├── WEB-INF │ │ ├── content │ │ │ └── show-messages.jsp │ │ └── web.xml │ └── index.jsp └── target ├── classes │ └── com │ └── example │ ├── webchat │ │ └── db │ │ ├── bean │ │ │ └── MessageBean.class │ │ └── dao │ │ ├── MessageDao.class │ │ └── impl │ │ └── MessageDaoOnMemoryImpl.class │ └── webchat2 │ └── webapp │ └── struts2 │ ├── SaveMessage.class │ └── ShowMessages.class ├── maven-archiver │ └── pom.properties ├── surefire ├── webchat2 │ ├── META-INF │ ├── WEB-INF │ │ ├── classes │ │ │ └── com │ │ │ └── example │ │ │ ├── webchat │ │ │ │ └── db │ │ │ │ ├── bean │ │ │ │ │ └── MessageBean.class │ │ │ │ └── dao │ │ │ │ ├── MessageDao.class │ │ │ │ └── impl │ │ │ │ └── MessageDaoOnMemoryImpl.class │ │ │ └── webchat2 │ │ │ └── webapp │ │ │ └── struts2 │ │ │ ├── SaveMessage.class │ │ │ └── ShowMessages.class │ │ ├── content │ │ │ └── show-messages.jsp │ │ ├── lib │ │ │ ├── asm-3.3.jar │ │ │ ├── asm-commons-3.3.jar │ │ │ ├── asm-tree-3.3.jar │ │ │ ├── commons-fileupload-1.2.2.jar │ │ │ ├── commons-io-2.0.1.jar │ │ │ ├── commons-lang-2.5.jar │ │ │ ├── freemarker-2.3.18.jar │ │ │ ├── javassist-3.11.0.GA.jar │ │ │ ├── ognl-3.0.4.jar │ │ │ ├── struts2-convention-plugin-2.3.1.2.jar │ │ │ ├── struts2-core-2.3.1.2.jar │ │ │ └── xwork-core-2.3.1.2.jar │ │ └── web.xml │ └── index.jsp └── webchat2.war
で、これをtomcatに読ませて
http://localhost:8080/webchat2/show-messages
にアクセスすれば動いてこんな画面が出る、はず。
おや、結果として文字エンコード用のFilterクラスとstruts-config.xmlが無くなった。
しかもjavaクラスのコード量は結構少なくなったし可読性も良い。