ウェブサイト検索

Struts 2 のアノテーションを使用した Hello World の例(struts.xml ファイルなし)


これはStruts 2チュートリアルシリーズの第2回の記事です。もし直接ここに来た場合は、以前の記事もチェックすることをお勧めします。Struts 2初心者向けチュートリアル 前回のチュートリアルでは、Struts 2アーキテクチャ、そのコンポーネントについて見て、XMLベースの設定(struts.xml)を使用してシンプルなStruts 2ウェブアプリケーションを構築しました。このチュートリアルでは、アノテーションや命名規則を使用して、Strutsの設定ファイルを完全に回避する方法を見ていきます。

Struts 2 コンベンションの概念

Struts 2は、アクションクラスと結果クラスを見つけるために2つの方法論を使用します。これらの方法論を使用するには、struts2-convention-plugin APIを使用する必要があります。通常のWebアプリケーションがある場合は、そのjarファイルをダウンロードしてWebアプリケーションのlibディレクトリに置くことができます。Mavenプロジェクトの場合は、以下のように依存関係を追加するだけで済みます。

<dependency>
	<groupId>org.apache.struts</groupId>
	<artifactId>struts2-convention-plugin</artifactId>
	<version>2.3.15.1</version>
</dependency>
  1. スキャン: この方法では、アクションクラスをスキャンする必要があるパッケージを指定します。Struts 2 フィルターのための設定は、以下のように web.xml で行う必要があります。

    <filter>
    	<filter-name>struts2</filter-name>
    	<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    	<init-param>
    		<param-name>actionPackages</param-name>
    		<param-value>com.journaldev.struts2.actions</param-value>
    	</init-param>
    </filter>
    

    Struts 2は、以下の方法でアクションクラスを見つけます。

    • @Action または @Actions アノテーションで注釈付けされた任意のクラス。
    • Actionインターフェースを実装するか、ActionSupportクラスを拡張する任意のクラス。
    • 名前が「Action」で終わり、execute()メソッドを含むクラス。これらのクラスでは、命名規則が使用されてアクションと結果が決定されます。
  2. 命名規則: Struts 2は、Actionで終わるクラス名に対して自動的にアクションを作成します。アクション名は、Actionサフィックスを削除し、最初の文字を小文字に変換することで決定されます。したがって、クラス名がHomeActionの場合、アクション名は「home」になります。これらのクラスが結果を提供するために@Resultで注釈が付けられていない場合、結果ページはWEB-INF/contentディレクトリ内に見に行かれ、名前は{action}-{return_string}.jspとなります。したがって、HomeActionアクションクラスが「success」を返す場合、リクエストはWEB-INF/content/home-success.jspページに転送されます。命名規則だけを使用すると非常に混乱しやすく、他のアクションクラスに対して同じJSPページを使用することはできません。したがって、これを避け、注釈ベースの構成を使用するように努めるべきです。

これで、アノテーションを使用してHello World Struts 2アプリケーションを作成する準備が整いました。Struts 2の設定ファイルは必要ありません。Eclipseで動的Webプロジェクトを作成し、Struts2AnnotationHelloWorldという名前にし、それをMavenプロジェクトに変換します。完成したプロジェクトは以下の画像のようになります。

Mavenの設定

pom.xmlにstruts2-coreとstruts2-convention-pluginの依存関係を追加しました。最終的なpom.xmlのコードは次のとおりです:

<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>Struts2AnnotationHelloWorld</groupId>
	<artifactId>Struts2AnnotationHelloWorld</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>

	<dependencies>
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-core</artifactId>
			<version>2.3.15.1</version>
		</dependency>
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-convention-plugin</artifactId>
			<version>2.3.15.1</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>
			<plugin>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.3</version>
				<configuration>
					<warSourceDirectory>WebContent</warSourceDirectory>
					<failOnMissingWebXml>false</failOnMissingWebXml>
				</configuration>
			</plugin>
		</plugins>
		<finalName>${project.artifactId}</finalName>
	</build>
</project>

デプロイメント記述子の設定

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xmlns="https://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	id="WebApp_ID" version="3.0">
	<display-name>Struts2AnnotationHelloWorld</display-name>

	<filter>
		<filter-name>struts2</filter-name>
		<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
		<init-param>
			<param-name>actionPackages</param-name>
			<param-value>com.journaldev.struts2.actions</param-value>
		</init-param>
	</filter>

	<filter-mapping>
		<filter-name>struts2</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

</web-app>

struts 2によってスキャンされるアクションクラスのパッケージを提供しているinit-param要素に注意してください。

結果ページ

私たちのアプリケーションには3つの結果ページがあります。login.jsp

<%@ page language="java" contentType="text/html; charset=US-ASCII"
    pageEncoding="US-ASCII"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<%-- Using Struts2 Tags in JSP --%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Login Page</title>
</head>
<body>
<h3>Welcome User, please login below</h3>
<s:form action="login">
	<s:textfield name="name" label="User Name"></s:textfield>
	<s:textfield name="pwd" label="Password" type="password"></s:textfield>
	<s:submit value="Login"></s:submit>
</s:form>
</body>
</html>
error.jsp
<%@ page language="java" contentType="text/html; charset=US-ASCII"
    pageEncoding="US-ASCII"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
    
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Error Page</title>
</head>
<body>
<h4>User Name or Password is wrong</h4>
<s:include value="login.jsp"></s:include>
</body>
</html>
welcome.jsp
<%@ page language="java" contentType="text/html; charset=US-ASCII"
    pageEncoding="US-ASCII"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Welcome Page</title>
</head>
<body>
<h3>Welcome <s:property value="name"></s:property></h3>
</body>
</html>

さて、アクションと結果ページを構成するために注釈を付けるアクションクラスを作成しましょう。

アノテーション付きアクションクラス

package com.journaldev.struts2.actions;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Actions;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Namespaces;
import org.apache.struts2.convention.annotation.Result;

import com.opensymphony.xwork2.ActionSupport;

/**
 * An empty class for default Action implementation for:
 * 
 *  <action name="home">
 *		<result>/login.jsp</result>
 *	</action>
 * HomeAction class will be automatically mapped for home.action
 * Default page is login.jsp which will be served to client
 * @author pankaj
 *
 */

@Namespaces(value={@Namespace("/User"),@Namespace("/")})
@Result(location="/login.jsp")
@Actions(value={@Action(""),@Action("home")})
public class HomeAction extends ActionSupport {
}

HomeActionは、login.jspページにリクエストを転送するだけの空のクラスであることに注意してください。

package com.journaldev.struts2.actions;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Namespaces;
import org.apache.struts2.convention.annotation.Result;

/**
 * Notice the @Action annotation where action and result pages are declared
 * Also notice that we don't need to implement Action interface or extend ActionSupport
 * class, only we need is an execute() method with same signature
 * @author pankaj
 *
 */
@Action(value = "login", results = {
		@Result(name = "SUCCESS", location = "/welcome.jsp"),
		@Result(name = "ERROR", location = "/error.jsp") })
@Namespaces(value={@Namespace("/User"),@Namespace("/")})
public class LoginAction {

	public String execute() throws Exception {
		if("pankaj".equals(getName()) && "admin".equals(getPwd()))
		return "SUCCESS";
		else return "ERROR";
	}
	
	//Java Bean to hold the form parameters
	private String name;
	private String pwd;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
}

@Action、@Actions、@Result、@Namespace、@Namespacesアノテーションの使用に注目してください。その使用法は明白です。さて、アプリケーションを実行すると、次の応答ページが得られます。

Struts2アノテーションのサンプルプロジェクトをダウンロードする

関連記事: