Руководство Struts2 для начинающих

1- Введение

Статья написана и основана на:
  • Eclipse 4.6 (NEON)
  • Struts 2 (2.3.20)
Вы смотрите руководство создания приложения Hello World Struts, используя  Annotation для конфигурации. Можете посмотреть похожий пример используя  XML для конфигурации по ссылке:

2- Создать Maven Project

  • File/New/Other..
Ввод:
  • Group Id: org.o7planning
  • Artifact Id: Struts2Annotation
  • Package: org.o7planning.struts2annotation
Project создан, и не обрщайте внимания при появлении сообщений об ошибке. Это потому что вы еще не объяявили библиотеку  Servlet.
Это иллюстрация  Project после завершения:

3- Конфигурация Maven

Конфигурировать Maven чтобы объявить использовенные библиотеки. Включает библиотеки  Servlet, Struts2.Так же конфигурируем  Maven Tomcat Plugin чтобы запустить приложения прямо в  Eclipse.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>org.o7planning</groupId>
    <artifactId>Struts2Annotation</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>Struts2Annotation Maven Webapp</name>

    <url>http://maven.apache.org</url>


    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>



        <!-- Servlet Library -->
        <!-- http://mvnrepository.com/artifact/javax.servlet/javax.servlet-api%20-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- Jstl for jsp page -->
        <!-- http://mvnrepository.com/artifact/javax.servlet/jstl%20-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>


        <!-- JSP API -->
        <!-- http://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api%20-->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
            <scope>provided</scope>
        </dependency>


        <!-- http://mvnrepository.com/artifact/org.apache.struts/struts2-core%20-->
        <dependency>
            <groupId>org.apache.struts</groupId>
            <artifactId>struts2-core</artifactId>
            <version>2.3.20</version>
        </dependency>

        <!-- http://mvnrepository.com/artifact/org.apache.struts/struts2-convention-plugin%20-->
        <dependency>
            <groupId>org.apache.struts</groupId>
            <artifactId>struts2-convention-plugin</artifactId>
            <version>2.3.20</version>
        </dependency>

    </dependencies>


    <build>
        <finalName>Struts2Annotation</finalName>
        <plugins>

            <!-- Config: Maven Tomcat Plugin -->
            <!-- http://mvnrepository.com/artifact/org.apache.tomcat.maven/tomcat7-maven-plugin%20-->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <!-- Config: contextPath and Port (Default: /Struts2Annotation : 8080) -->
                <!-- <configuration> <path>/</path> <port>8899</port> </configuration> -->
            </plugin>


        </plugins>
    </build>

</project>
 

4- Конфигурация Struts & web.xml

Использовать Webapps >= 3
web.xml
<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns="http://java.sun.com/xml/ns/javaee"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
          http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
     id="WebApp_ID" version="3.0">
 
    <display-name>Struts2Annotation</display-name>


    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>
            org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
        </filter-class>
    </filter>

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

    <welcome-file-list>
        <welcome-file>/WEB-INF/pages/helloStruts2.jsp</welcome-file>
    </welcome-file-list>
    

</web-app>
struts.xml это файл  resource который должен находиться в  src/main/resources, этот файл выполняет обязанность конфигурации  struts.
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
   "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
   "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>

   <constant name="struts.enable.DynamicMethodInvocation" value="false" />
   <constant name="struts.devMode" value="false" />
   <constant name="struts.custom.i18n.resources" value="ApplicationResources" />

</struts>

5- Code Project

ApplicationResources.properties
label.username= Username
label.password= Password
label.login= Login
error.login= Invalid Username/Password. Please try again.
_menu.jsp
<%@ page language="java" contentType="text/html; charset=Ù-8"
    pageEncoding="UTF-8"%>



<a href="${pageContext.request.contextPath}/">Home</a>
 |
<a href="${pageContext.request.contextPath}/login">Login</a>
 
 <br>
helloStruts2.jsp
<html>
<head>
<title>Struts 2 - Hello World</title>
</head>

<body>

    <jsp:include page="_menu.jsp" />

    <h2>Hello Struts2</h2>


</body>

</html>
login.jsp
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<html>
<head>
<title>Struts 2 - Login Application</title>
</head>

<body>

    <jsp:include page="_menu.jsp" />


    <h2>Struts 2 - Login Application</h2>
    <s:actionerror />

    <s:form action="/login" method="post">
        <s:textfield name="username" key="label.username" size="20" />
        <s:password name="password" key="label.password" size="20" />
        <s:submit method="execute" key="label.login" align="center" />
    </s:form>
    
    <br>
    Username: admin, password: admin123

</body>

</html>
userInfo.jsp
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<html>
<head>
<title>User Info</title>
</head>

<body>
   <jsp:include page="_menu.jsp" />
   
   <h2>Howdy, ${loginedUsername}...!</h2>
</body>
</html>
HelloAction.java
package com.o7planning.struts2annotation.action;

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

import com.opensymphony.xwork2.ActionSupport;

@Action(value = "hello", //
results = { //
        @Result(name = "helloPage", location = "/WEB-INF/pages/helloStruts2.jsp")
} //
)
public class HelloAction  extends ActionSupport {
 
    private static final long serialVersionUID = 1L;

    @Override
    public String execute() {
         
        return "helloPage";
    }
   
}
LoginAction.java
package com.o7planning.struts2annotation.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Result;

import com.opensymphony.xwork2.ActionSupport;

@Action(value = "login", //
		results = { //
				@Result(name = "showForm", location = "/WEB-INF/pages/login.jsp"), //
				@Result(name = "loginError", location = "/WEB-INF/pages/login.jsp"), //
				// loginSuccess: Redirect to /userInfo
				@Result(name = "loginSuccess", type="redirect", location= "/userInfo") //
		} //
)
public class LoginAction extends ActionSupport {

	private static final long serialVersionUID = 7299264265184515893L;
	private String username;
	private String password;

	public LoginAction() {

	}

	@Override
	public String execute() {
		if (this.username == null && this.password == null) {
			return "showForm";
		} 
		HttpServletRequest request = ServletActionContext.getRequest();
		
		// Username и password действительны.
		if ("admin".equals(this.username) && "admin123".equals(this.password)) {
			HttpSession session = request.getSession();
			
			// Сохранить userName в session.
			session.setAttribute("loginedUsername", this.username);
			
			return "loginSuccess";
		}
		// Username или password неправильный
		else {
			// ** Смотреть в ApplicationResources.properties
			String message = getText("error.login");

			addActionError(message);

			return "loginError";
		}
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

}
UserInfoAction.java
package com.o7planning.struts2annotation.action;

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

import com.opensymphony.xwork2.ActionSupport;

@Action(value = "userInfo", //
results = { //
        @Result(name = "userInfoPage", location = "/WEB-INF/pages/userInfo.jsp")
} //
)
public class UserInfoAction  extends ActionSupport {
 
    private static final long serialVersionUID = 1L;

    @Override
    public String execute() {
        
        return "userInfoPage";
    }
    
}

6- Запуск приложения

Чтобы запустить приложение прямо в  Eclipse, вам нужна конфигурация запуска  Tomcat Maven Plugin.
Ввод:
  • Name: Run Struts2Annotation
  • Base Directory: ${workspace_loc:/Struts2Annotation}
  • Goals: tomcat7:run
Tomcat Maven Plugin запущен:
В браузере, введите URL:
И URL:
Если вы ввели неправильные  Username/password, страница отобразит следущее:
При правильном вводе:

7- Правила работы Struts 2 (Annotaion version)

Поток приложения:
Как  Struts найти подходящий класс  Action?
  1. Библиотека struts2-convention-plugin-*.jar выполняет обязанность поиска.
  2. Она читает в struts2.xml чтобы посмотреть инструкцию если есть, в противном случае она ищет с помощью руководства по умолчанию в Struts.
  3. По умолчанию:
    • Искать классы с названиями, оканчивающимися на Action.
    • Искать классы с названием package окачивающиеся наi: action, actions, struts, struts2.
Поэтому вы должны назвать классы  Action по правилам выше, или конфигурировать ваши собственные правила в struts2.xml