Struts2 Tutorial for Beginners
1. Instroduction
This document was written based on:
- Eclipse 4.6 (NEON)
- Struts 2 (2.3.20)
You are viewing "Hello World Struts2 - Annotation Example". You can view the same example using the XML at:
2. Create Maven Project
- File/New/Other..



Enter:
- Group Id: org.o7planning
- Artifact Id: Struts2Annotation
- Package: org.o7planning.struts2annotation
Do not worry about the error message when the Project has been created. The reason is that you do not declare the Servlet library.


This is the image after Project Completion:

3. Configuring Maven
Configuring Maven to declare the library used. Includes library Servlet, Struts2. Also configure Tomcat Maven Plugin for running web applications directly on 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 -->
<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 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- JSP API -->
<!-- http://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
<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 -->
<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 -->
<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 -->
<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. Configuring Struts & web.xml
Using Webapp >= 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 is a resource file, it should be placed in src/main/resources, this file is used to configure the 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=UTF-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();
// Valid username and password
if ("admin".equals(this.username) && "admin123".equals(this.password)) {
HttpSession session = request.getSession();
// Store userName in session
session.setAttribute("loginedUsername", this.username);
return "loginSuccess";
}
// Invalid username or password
else {
// ** See in 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. Run Application
To run the application directly on Eclipse, you need to configure to run Tomcat Maven Plugin.


Enter:
- Name: Run Struts2Annotation
- Base Directory: ${workspace_loc:/Struts2Annotation}
- Goals: tomcat7:run


Tomcat Maven Plugin is running:

In the browser, enter the URL:

And URL:

If you entered an incorrect username/password, page will be displayed as shown below:

Else:

7. The operation principle of Struts2 (Annotation version)
The flow of the application :

How Struts found a suitable Action class?

- Library struts2-convention-plugin-*.jar will search an appropriate Action class.
- It reads in struts2.xml to see your instructions if there is any, otherwise it will search by default Struts instructions.
- Default:
- Search Action classes has name ends with Action.
- Search the class that package name ends with: action, actions, struts, struts2.
Therefore, the Action class must be named according to the rule above, or must configure your own rules in struts2.xml.