זהו המאמר השני בסדרת השורות של הדרכות Struts 2. אם הגעתם ישירות לכאן, אני ממליץ לבדוק גם את הפוסט הקודם. הדרכה למתחילים ב-Struts 2 במדריך האחרון, בדקנו את ארכיטקטורת Struts 2, את רכיביה ובנינו אפליקציה פשוטה של Struts 2 עם הגדרה מבוססת XML (struts.xml). במדריך זה, נראה איך ניתן להימנע מקובץ התצורה של Struts באופן מוחלט באמצעות אנוטציות או קונבנציות שמות.
מושג קונבנציה ב-Struts 2
Struts 2 משתמשת בשניות שיטות לזיהוי של מחלקות פעולה ומחלקות תוצאה. עלינו להשתמש ב- API של struts2-convention-plugin כדי להשתמש באחת מהשיטות הללו. אם יש לכם אפליקציה רגילה, תוכלו להוריד את קובץ ה-JAR שלו ולשים אותו בתיקיית lib של האפליקציה בתוך ה-Web. לפרוייקטי 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 והשם צריך להיות {action}-{return_string}.jsp. אם כיתת הפעולה HomeAction מחזירה "success", הבקשה תועבר לדף WEB-INF/content/home-success.jsp. שימוש רק בתקנת שמות יכול להיות מבלבל מאוד ואנחנו לא יכולים להשתמש באותו דף JSP עבור כיתות פעולה אחרות. כך שאנחנו צריכים לנסות למנוע זאת ולהשתמש בהגדרת האנוטציה.
עכשיו אנו מוכנים ליצור את יישום ה- Hello World שלנו ב- Struts 2 באמצעות הערות ולא נצטרך קובץ הקונפיגורציה של Struts 2. יצירת פרויקט אינטרנט דינמי באקליפס Struts2AnnotationHelloWorld והמרתו לפרויקט Maven. הפרויקט הסופי נראה כמו התמונה שלמטה.
תצורת Maven
הוספנו תלות ב- struts2-core ו- struts2-convention-plugin ב- pom.xml, קוד ה-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, תגישו לב שזה כמעט אותו דבר. השינוי היחידי הוא בדרך שבה אנו מחברים את מחלקות הפעולה ודפי התוצאה של היישום שלנו.