アノテーションベースでStruts2のActionクラスを記述する(2016 Spring Ver.)

# アノテーションを使ったActionの設定

アノテーションを使ったActionクラスの設定は、Struts2の公式プラグインの1つである[Struts2-Convention-plugin](http://struts.apache.org/release/2.3.x/docs/convention-plugin.html)を導入すると可能です。
Actionクラスの設定は、struts.xml(ないしはその派生xmlファイル)に記述するルールですが、Conventionプラグインを使うことで、個別のActionクラスの設定をxmlに分離せず、Actionクラスに直接記載できます。

## 対応バージョン

Struts2.1.x , 2.2.x , 2.3.x , 2.5

## 導入方法
入手方法はいくつかあります。お好みでどれか1つをお選びください。

:blush: [Pleiades All in one Eclipseを用いたStruts2公式ブランクプロジェクトの導入](http://qiita.com/alpha_pz/items/e2feb0fd99c002032a52) がてっとり早いです 

1. [Struts2公式サイト](http://struts.apache.org/download.cgi)からStruts2一式をダウンロードして解凍した後、struts2-convention-plugin-2.5.jar(ないしは最新版)を/WEB-INF/libコピーする。
2. mavenを使ってjarを追加する。
3. 公式サイトからStruts2-conventionのmavenアーキタイプ(導入方法:https://struts.apache.org/docs/struts-2-maven-archetypes.html) を導入してアプリケーションを構成する。

Conventionプラグインの導入には、設定ファイルの追記や編集は不要です。

## アノテーションで設定できるもの

struts.xmlで設定できること＝アノテーションで全て可能です。Actionクラスの設定方法そのものが柔軟性をもっていますので、記述パターンもいくつかあります。ここでは使いやすい内容で紹介します。

|アノテーション|役割|記述例|
|:---|:---|:---|:---|:---|
|@Namespace|Actionクラスが属する名前空間。URLの一部になる。|@Namespace("/")|
|@ParentPackage|Actionクラスが継承する名前空間。指定したパッケージの設定を引き継く。|@ParentPackage("struts-default")|
|@Result|Actionクラスのreturn値と出力先を設定する。親要素に@Resultsを持つ|@Result(name = ActionSupport.SUCCESS, location = "form" , type="dispatcher")|
|@Action|Actionクラスであることを宣言。URLの一部になる。親要素に@Actionsを持つ|@Action("")|
|@InterceptorRef|Actionクラスが使うインターセプタを変更する。親要素に@InterceptorRefsをもつ|@InterceptorRef("defaultStack")|
|@ExceptionMapping|Actionクラスで例外をキャッチした時の例外クラスとresultの値を定義する。親要素に@ExceptionMappingsを持つ|@ExceptionMapping(exception="java.lang.Exception" , result="exception")|

+ アノテーションのNamespace（名前空間）=struts.xmlのpackage要素と同じです。
+ 入力値検証(Validation)のアノテーションは、Conventionプラグインに含まれません。
+ Actionはpublicメソッドに記載すると記述量が減ります。Actionsが不要になります。

## 記載例 

以下に設定例を示します。

```java:SampleAction.java
/**
 *
 */
package lumi.action.sample;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.ExceptionMapping;
import org.apache.struts2.convention.annotation.ExceptionMappings;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;

import com.opensymphony.xwork2.ActionSupport;

/**
 * @author A-pZ
 *
 */
@Namespace("/sample")
@ParentPackage("struts-default")
@Results({
	@Result(name = ActionSupport.SUCCESS, location = "index.jsp" , type="dispatcher"),
})
@ExceptionMappings({
	@ExceptionMapping(exception="java.lang.Exception" , result="exception")
})
public class SampleAction extends ActionSupport {
	@Action("display")
	public String sample() throws Exception {
		return SUCCESS;
	}
}
```

このActionクラスは、/sample/display または /sample/display.action でリクエストできます。
つまり、@Namespaceの値/@Actionの値 となります。

## @Resultのlocationで指定したファイルの配置場所

Conventionプラグインのデフォルト設定では、必ず次の場所に配置したものを読み込みます。

```xml
/WEB-INF/content/@Namespaceの値/@Resultのlocation属性値
```

先ほどの例では、/WEB-INF/content/sample/index.jspとなります。

## 他のフレームワークと組み合わせた例

ここでは例のみ挙げますが、Struts2+Spring3+Lombokを組み合わせて記載した例も紹介します。

[Gist:現在のActionクラスの例(Struts2+Spring3+Lombok)](https://gist.github.com/A-pZ/1a3dccaec467c07d0a50)