kagamihogeの日記

kagamihogeの日記です。

JBoss AS7でStruts2 2.3をうごかした

環境

  • jdk1.7.0_09
  • Eclipse4.2.0 SR1
  • JBoss AS 7.1.1.Final
  • m2e
  • JBoss Tools 4.0
  • Struts2 2.3.4.1

やったこと

JBoss CentralからDynamic Web Projectを選択。

サンプルとしてプロジェクト名をjbossas7struts2にしておく。Dynamic web module versionはこのさいだから試しに3.0にしておく。

Mavenを使えるようにするため、プロジェクト右クリック -> Configure -> Convert to Maven Projectを選ぶ。そのあと、プロジェクト右クリック -> Maven -> Update Projectする。

ついでにプロジェクトの文字コードUTF-8にしておく。

pom.xmlにStruts2のdependencyを追加する。プロジェクトをjboss tools経由で作った関係でjboss関連のdependencyが追加された状態になるが、それらは一旦すべて削除する。Struts2のバージョンは2012/10/20最新の2.3.4.1を使う。struts2-convention(いわゆるCoCをやってくれる)のライブラリも追加する。

<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>jbossas7struts2</groupId>
    <artifactId>jbossas7struts2</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>org.apache.struts</groupId>
            <artifactId>struts2-core</artifactId>
            <version>2.3.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.struts</groupId>
            <artifactId>struts2-convention-plugin</artifactId>
            <version>2.3.4.1</version>
        </dependency>
    </dependencies>
</project>

web.xmlにStruts2用のサーブレットフィルターを追加する。2.1.3まではFilterDispatcherだったがそれはdeprecatedになっており、それ以降はStrutsPrepareAndExecuteFilterを使えとのことなので、それを使う。参考:Struts2メモ - Asterisk Works Wiki

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
    <display-name>jbossas7struts2</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>

クラスパスの通ってるディレクトリにsturts.xmlを作成する。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
      "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
      "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
	<constant name="struts.convention.result.path" value="/" />
</struts>

アクションを作る。

package struts2test.action;

import com.opensymphony.xwork2.Action;

public class SampleHogeAction {
    public String execute() throws Exception {
        System.out.println("struts2test.action.SampleHogeAction#execute");
        return Action.SUCCESS;
    }
    
    public String getMessage() {
        return "テストメッセージ";
    }
}

ResultのJSPをWebContent直下に、sample-hoge.jspというファイル名で作る。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags" %>  
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<s:property value="message" />
</body>
</html>

http://localhost:8080/jbossas7struts2/sample-hoge.action とか http://localhost:8080/jbossas7struts2/sample-hoge ブラウザでアクセスすると「テストメッセージ」と表示される。

最終的なプロジェクトの構成はこんなかんじ。

はまりどころなど

JBAS011006: Not installing optional component org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter due to exception: java.lang.ClassNotFoundException:

サーブレットフィルタに指定したクラスが無いとかでデプロイが失敗する。デプロイ先であるところの%JBOSS_HOME%\standalone\deployments\jbossas7struts2.war\WEB-INF\libを覗くと確かにライブラリのjarファイルが無い。

というわけで、とりあえずはMavenで取得したjarをWebConten\WEB-INF\libに突っ込む設定にしておく。

プロジェクト右クリック -> Deployment Assembly*1 で Add -> Java Build Path Entries -> Maven Dependencies を選ぶ。SouruceがMaven Dependencies、Deploy PathがWEB-INF/libになってればOK。

Could not find action or result: There is no Action mapped for namespace [/] and action name [example] associated with context path

URLのパスとStruts2のアクションのクラスとのマッピングが見つからない、というエラー。Struts2は、基本的にはstruts.xmlかクラスのアノテーションでURLとのマッピングを定義するのだけど、struts2-conventionを使うことでその定義を自動的にやってくれるようになる。マッピングのルールは他のサイトを参考。それで、このエラーはstruts2-convention-pluginのライブラリが無いことで発生する。

というわけで、pom.xmlにstruts2-convention-pluginのdependencyを追加すればOK。

Could not find action or result: No result defined for action struts2test.action.SampleHogeAction and result success

URLからアクションは見つかったけれども、ResultであるJSPが見つからない、というエラー。ためしに、return Action.SUCCESS;をreturn Action.NONE;に変えてみると、JSPに飛ばないのでエラーは出なくなる。conventionのためResultを明示的に指定しないので、conventionのResultのJSPのパスを自動的に見つけだす設定がおかしい、ということになる。

というわけで、struts.xmlに下記の行を追加すればOK。

<constant name="struts.convention.result.path" value="/" />
JSPが更新されない(未解決)

actionというかjavaは修正すれば即時に反映される、いわゆるホットデプロイが利くのだけど。JSPは更新してもjbossを再起動というかデプロイしなおすまで反映されない。jbossがどうこうっていうより、WebConten以下のファイルがデプロイ先のフォルダにコピーされるような設定にしないといけない気がするんだけど、やり方がわからない。

かんそう

xmlがもっさりとか継承しないといけないクラスがあったりとか、Struts1.xのゴテゴテ感はどこへやら。CoCありーの、POJOでOKだったりので、随分とまぁシンプルなフレームワークになったものだなぁと。CoCの規約に振り回されるハマりがイヤならアノテーションでマッピングすれば良いし、実は使い勝手ソレナリにいいんじゃなかろうか……という気がする。

*1:昔のEclipseでいうところのJava EE Module Dependenciesが置き換えられたものとのこと