Since Struts 2.1, the framework provides the Convention Plugin that allows developers writing action classes and wiring them with result views without any configuration (no struts.xml required). Indeed, this can be done by following some standard naming conventions and defaults specified by the Convention Plugin.

In this article, we’d like to show you how to implement a simple Struts2 application using naming conventions instead of XML or annotations configuration.

Table of contents:

    1. The Convention Plugin
    2. Conventions for action classes
    3. Conventions for results and JSP pages
    4. Code of input page
    5. Code of action class
    6. Code of result pages
    7. Code of web.xml
    8. Required jar files
    9. Testing the application

First, let’s take a look at the Convention plugin.

1. The Convention Plugin

This plugin enables zero-configuration for Struts2 application by enforcing the standard naming conventions. It comes with Struts2 distribution since version 2.1 and replaces the old Codebehind Plugin and Zero Config plugins. To use this plugin, simply put its jar file under WEB-INF\lib directory of your web application:

struts2-convention-plugin-VERSION.jar

Or if you are using Maven, put the following entry in the pom.xml file:

<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-convention-plugin</artifactId>
    <version>VERSION</version>
</dependency>

Now let’s explore some primary conventions.


2. Conventions for action classes

  • Scanning algorithm:
    • The Convention plugin searches in the packages having the following words in their names: struts, struts2, action, or actions.
    • Under the matching packages (and sub-packages), the plugin looks for the classes that are either:
      • Implementing the com.opensymphony.xwork2.Action interface (either directly or extending its subclass com.opensymphony.xwork2.ActionSupport)
      • Having their names end with Action.
    • For example, the following classes will be found by the Convention plugin:

      Classes

      Reasons

      net.codejava.struts.HelloWorldAction

      Package name has “struts” and class name ends with “Action”.

      net.codejava.actions.LoginAction

      Package name has “actions” and class name ends with “Action”.

      net.codejava.struts2.services.FileDownload

      Package name has “struts2” and class implements the com.opensymphony.xwork2.Action interface.

       

  • Action class to URL mapping convention:
    • The plugin will map each action class to a specific URL, following this rules:
      • Remove the word Action at the end of class name.
      • Convert the uppercase letters to lowercase ones and add dashes among them.
      • If there sub-packages after the words struts, struts2, action or actions, then the sub-package names will be converted to namespaces in the URL.
    • For example, the above action classes will be mapped to the following URLs:

      Action Classes

      URLs

      net.codejava.struts.HelloWorldAction

      /hello-world

      net.codejava.actions.LoginAction

      /login

      net.codejava.struts2.services.FileDownload

      /services/file-download

       

  • Default action method: When an action’s URL is invoked, the plugin will invoke the action’s execute()method.

    Recommended Book: Struts 2 Design and Programming: A Tutorial (A Tutorial series)


3. Conventions for results and JSP pages

The default location where the plugin looks for JSP pages corresponding to result codes returned from the action’s execute() method is WEB-INF/content directory. The following table shows how the plugin searches for the JSP pages based on the result codes:

URLs

Result codes

Matching JSP pages

/hello-world

success

/WEB-INF/content/hello-world.jsp

/hello-world

success

/WEB-INF/content/hello-world-success.jsp

/login

success

/WEB-INF/content/login.jsp

/login

error

/WEB-INF/content/login-error.jsp

/login

input

/WEB-INF/content/login-input.jsp

/services/file-download

success

/WEB-INF/content/services/file-download.jsp

/services/file-download

error

/WEB-INF/content/services/file-download-error.jsp

NOTE:

    • If the plugin could not find a JSP page that matches a result code, it will find a JSP page for the “success” code instead. If there is no JSP page for “success” code, a 404 error will be returned.
    • The plugin allows accessing JSP pages in the WEB-INF/content directory even when there are no associated action classes. This is called actionless results. For example, if we have a JSP file named hello-world.jsp in the WEB-INF/content directory, we can access it by this URL: /hello-world

Now let’s dive into a complete sample Struts2 application which applies the above conventions. The sample application shows a form that allows users entering two numbers X and Y. When the users submit the form, an action is called to calculate division of the two numbers and return result. If the dividing number is zero, an error page is returned.

Create an Eclipse project with the following structure:

Struts2ZeroConfig project structure


4. Code of input page

Here is source code of the input.jsp file under WEB-INF/content directory:

<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
	"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Input Form</title>
</head>
<body>
	<center>
		<h2>Calculate Division of X/Y</h2>
		<s:form action="calculate" method="post">
			<s:textfield name="x" label="Enter X" />&nbsp;&nbsp;
			<s:textfield name="y" label="Enter Y" />
			<s:submit />
		</s:form>
	</center>
</body>
</html>

The form contains two text fields and it will call the action /calculate when submitted.

 


5. Code of action class

Source code of the CalculateAction.java under the package net.codejava.struts:

package net.codejava.struts;

import com.opensymphony.xwork2.ActionSupport;

public class CalculateAction extends ActionSupport {
	private int x;
	private int y;
	private float division;

	public String execute() {
		// calculates division
		if (y == 0) {
			return ERROR;
		}
		
		division = x / y;
		return SUCCESS;
	}

	public int getX() {
		return x;
	}

	public void setX(int x) {
		this.x = x;
	}

	public int getY() {
		return y;
	}

	public void setY(int y) {
		this.y = y;
	}

	public float getDivision() {
		return division;
	}

	public void setDivision(float division) {
		this.division = division;
	}	
}

The action class declares two variables x, y and division with corresponding getters and setters. Its execute() method returns ERROR code if y equals to zero, otherwise returns SUCCESS code. That means we should create two JSP pages corresponding to these two result codes.

Recommended Book: Apache Struts 2 Web Application Development


6. Code of result pages

Source code of the calculate-success.jsp (for SUCCESS result code) under WEB-INF/content directory:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
	"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Division Result</title>
</head>
<body>
	<h3>
		Result of ${x} / ${y} is ${division}
	</h3>
</body>
</html>

And source code of the calculate-error.jsp (for ERROR result code) under WEB-INF/content directory:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
	"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Division Error</title>
</head>
<body>
	<h3>
		Cannot divide by zero!
	</h3>
</body>
</html>

 

7. Code of web.xml

Enable Struts2’s dispatcher filter in the web.xml as follows:

<?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" 
	xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
	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>Struts2ZeroConfig</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>
</web-app>

 

 

8. Required jar files

Add the following jar files into WEB-INF\lib directory (including the Convention Plugin’s jar file):

    1. asm-3.3.jar
    2. asm-commons-3.3.jar
    3. asm-tree-3.3.jar
    4. commons-fileupload-1.2.2.jar
    5. commons-io-2.0.1.jar
    6. commons-lang3-3.1.jar
    7. commons-logging-1.1.1.jar
    8. commons-logging-api-1.1.jar
    9. freemarker-2.3.19.jar
    10. javassist-3.11.0.GA.jar
    11. ognl-3.0.6.jar
    12. struts2-convention-plugin-2.3.8.jar
    13. struts2-core-2.3.8.jar
    14. xwork-core-2.3.8.jar

These jar files come from Struts 2.3.8 GA distribution.


9. Testing the application

Now let’s test the application we have built. Deploy it on Tomcat and type the following URL into browsers’ address bar:

http://localhost:8080/Struts2ZeroConfig/input

The input form is displayed. Enter two numbers as follows:

input form

Then hit Submit, the result page is displayed:

result page

If we enter 0 for Y, the error page is displayed:

error page

Wow! The application is working perfectly, as we can notice: there is no configuration at all (except the configuration of Struts2 framework in the web.xml file). So using standard naming conventions would be an alternative way to XML configuration as it helps reducing the amount of code to write.

 

Recommended Book: Struts 2 in Action

Attachments:
Download this file (Struts2ZeroConfig.war)Struts2ZeroConfig.war[Deployable WAR file]3563 kB
Download this file (Struts2ZeroConfig.zip)Struts2ZeroConfig.zip[Eclipse project]3566 kB
Start learning on Udemy today!