o7planning

Struts2 Tutorial for Beginners

  1. Instroduction
  2. Create Maven Project
  3. Configuring Maven
  4. Configuring Struts & web.xml
  5. Code Project
  6. Run Application
  7. The operation principle of Struts2 (Annotation version)

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.