Dies ist der zweite Artikel in der Serie der Struts 2 Tutorials. Wenn Sie direkt hierher gekommen sind, würde ich empfehlen, auch den früheren Beitrag zu überprüfen. Struts 2 Anfängertutorial Im letzten Tutorial haben wir uns die Struts 2 Architektur angesehen, die Komponenten und eine einfache Struts 2 Webanwendung mit XML-basierter Konfiguration (struts.xml) erstellt. In diesem Tutorial werden wir sehen, wie wir die Struts-Konfigurationsdatei vollständig vermeiden können, indem wir Annotationen oder Namenskonventionen verwenden.
Struts 2 Konventionskonzept
Struts 2 verwendet zwei Methodologien, um die Aktionsklassen und Ergebnisklassen zu ermitteln. Wir müssen die struts2-convention-plugin-API verwenden, um eine dieser Methodologien zu verwenden. Wenn Sie eine normale Webanwendung haben, können Sie die JAR-Datei herunterladen und in das Webanwendungslib-Verzeichnis stellen. Für Maven-Projekte können Sie einfach die Abhängigkeit wie unten angegeben hinzufügen.
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-convention-plugin</artifactId>
<version>2.3.15.1</version>
</dependency>
-
Scannen: Bei dieser Methode geben wir das Paket an, das nach Aktionsklassen durchsucht werden soll. Die Konfiguration muss für den Struts 2-Filter in der web.xml-Datei wie folgt durchgeführt werden.
<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 wird Aktionsklassen auf folgende Weise finden.
- Jede Klasse, die mit @Action oder @Actions Annotationen versehen ist.
- Jede Klasse, die das Action-Interface implementiert oder die ActionSupport-Klasse erweitert.
- Jede Klasse, deren Name mit Action endet und die die execute() Methode enthält. Für diese Klassen wird die Namenskonvention verwendet, um Aktion und Ergebnisse zu bestimmen.
-
Namenskonvention: Struts 2 erstellt automatisch Aktionen für Klassen mit einem Namen, der mit Action endet. Der Aktionsname wird durch Entfernen des Suffix Action und Konvertieren des ersten Buchstabens in Kleinbuchstaben bestimmt. Wenn beispielsweise der Klassenname HomeAction lautet, ist die Aktion „home“. Wenn diese Klassen nicht mit @Result annotiert sind, um das Ergebnis anzugeben, werden die Ergebnisseiten im Verzeichnis WEB-INF/content gesucht, und der Name sollte {Aktion}-{Rückgabestring}.jsp sein. Wenn die HomeAction-Aktionsklasse beispielsweise „success“ zurückgibt, wird die Anfrage an die Seite WEB-INF/content/home-success.jsp weitergeleitet. Die alleinige Verwendung der Namenskonvention kann sehr verwirrend sein, und wir können dieselbe JSP-Seite nicht für andere Aktionsklassen verwenden. Daher sollten wir versuchen, dies zu vermeiden und eine konfigurationsbasierte Annotation zu verwenden.
Jetzt sind wir bereit, unsere Hello World Struts 2-Anwendung mit Annotationen zu erstellen, und wir benötigen keine Struts 2-Konfigurationsdatei. Erstellen Sie ein dynamisches Webprojekt in Eclipse Struts2AnnotationHelloWorld und konvertieren Sie es in ein Maven-Projekt. Das endgültige Projekt sieht wie folgt aus (siehe Bild unten).
Maven-Konfiguration
Wir haben die Abhängigkeiten struts2-core und struts2-convention-plugin in die pom.xml aufgenommen, der endgültige Code der pom.xml lautet:
<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>
Bereitstellungsdienst-Konfiguration
<?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>
Beachten Sie das init-param-Element, in dem wir das Aktionen-Klassenpaket angeben, das von Struts 2 gescannt wird.
Ergebnisseiten
In unserer Anwendung haben wir drei Ergebnisseiten. 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>
Erstellen wir nun unsere Aktionen-Klassen, die wir mit Annotationen konfigurieren werden.
Aktionsklassen mit Annotationen
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 {
}
Beachten Sie, dass HomeAction eine leere Klasse ist, die nur dazu dient, die Anforderung zur Seite login.jsp weiterzuleiten.
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 zum Speichern der Formparameter
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;
}
}
Beachten Sie die Verwendung der Annotationen @Action, @Actions, @Result, @Namespace und @Namespaces, die Verwendung ist selbsterklärend. Wenn wir jetzt unsere Anwendung ausführen, erhalten wir folgende Antwortseiten.
Wenn Sie den letzten Beitrag gelesen haben, in dem wir dieselbe Anwendung mit der Konfiguration struts.xml entwickelt haben, werden Sie feststellen, dass es fast identisch ist. Der einzige Unterschied besteht darin, wie wir unsere Anwendungsaktionen und Ergebnisseiten verknüpfen.