這是《Struts 2 教程系列》的第二篇文章。如果你是直接來到這裡的,我建議你也去看看之前的文章。Struts 2 初學者教程 在上一篇教程中,我們研究了 Struts 2 的架構、其組件並建立了一個簡單的 Struts 2 網絡應用程序,使用基於 XML 的配置(struts.xml)。在這篇教程中,我們將看到如何完全避免使用 Struts 配置文件,而是使用註釋或命名慣例。
Struts 2 公約概念
Struts 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>
-
掃描: 在這種方法中,我們指定需要掃描的套件以查找動作類。配置需在 web.xml 中為 Struts 2 過濾器完成,如下所示。
<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 將根據以下方法查找動作類。
-
命名慣例:Struts 2將自動為以Action結尾的類別建立動作。動作名稱是通過刪除Action後綴並將首字母轉換為小寫來確定的。因此,如果類別名稱是HomeAction,則動作將是“home”。如果這些類別未使用@Result註釋來提供結果,則結果頁面將在WEB-INF/content目錄中查找,並且名稱應為{動作}-{返回字符串}.jsp。因此,如果HomeAction動作類別返回“success”,請求將被轉發到WEB-INF/content/home-success.jsp頁面。僅使用命名慣例可能非常令人困惑,我們無法將同一個JSP頁面用於其他動作類別。因此,我們應該儘量避免這種情況並使用基於註釋的配置。
現在,我們準備使用標註來創建我們的 Hello World Struts 2 應用程序,並且我們將不再需要 Struts 2 配置文件。在 Eclipse 中創建一個名為 Struts2AnnotationHelloWorld 的動態 Web 項目,並將其轉換為 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>
注意 init-param 元素,我們提供了將被 Struts 2 掃描的動作類別套件。
結果頁面
我們的應用程式中有三個結果頁面。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 用於保存表單參數
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註釋,使用方法自明。 現在當我們運行應用程序時,我們會得到以下響應頁面。
如果您已閱讀上一篇文章,我們已經使用struts.xml配置開發了相同的應用程序,您會注意到它幾乎相同。 唯一的變化是我們連接應用程序動作類和結果頁面的方式。