How to map the Struts 2 action through Annotations (@Result)

January 18th, 2009  | Tags: , ,

Java 1.5 brought an interesting feature: Annotations. Boring things, like mapping, can do now through Annotations.

Many frameworks are using Annotations, such as: Hibernate, Spring, EJB 3, JUnit and so on.

Struts 2 also uses the annotation feature, majority for validation, however many people do not know that a simple Action can be mapped through Annotation instead the struts.xml file. This post teaches how to do that, and believe, it’s really simple :).

The project

There are, at least, 3 ways to create a new Struts 2 project:

  1. Using the Struts 2 blank application
  2. Creating a new project and adding the required JARs yourself
  3. Using Maven 2 (archetypes) to create the application

My choice, as always, is the number 3. By the way, if you’re working in a real project without a build tool, consider to study/use MAVEN 2, it is really fantastic.

Creating the Project through Maven 2

First of all, you should install Maven 2 in your machine. If you’re using Eclipse, I advice you to install the M2Eclipse plugin. A good starting point is here.

To create a new project either using maven 2, simply type the following into the console:

mvn archetype:create -DgroupId=tutorial \
    -DartifactId=tutorial \
    -DarchetypeGroupId=org.apache.struts \
    -DarchetypeArtifactId=struts2-archetype-starter \
    -DarchetypeVersion=2.0.5-SNAPSHOT \
    -DremoteRepositories=http://people.apache.org/repo/m2-snapshot-repository

or using the M2Eclipse plugin, through File -> New -> Other -> Maven Project. Use struts2-archetype-starter as archetype.

Maven will create a Struts 2 project, with Spring framework as IoC, DWR, Sitemesh, JUnit, as well as two Action files and one DateConverter as example. As I said, Maven is fantastic, isn’t it?

Note: By default, Sitemesh is enabled in the Maven project. For our example, let’s disable it. To do that, simple edit the web.xml file and comment the filter and filter-mapping regarding sitemesh.

Coding the files. JSPs and Struts Action

Our example is really simple. There will be 2 JSPs (index.jsp and result.jsp) and a simple struts action (HelloWorldAction.java). Let’s code them and after that, let’s show up the difference between the tradicional mapping (through struts.xml) and annotations mapping.

Note: Who has created the project through maven, you’ll see some files already created. Fell free to remove them (before a backup, of course).

index.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@taglib prefix="s" uri="/struts-tags" %>    
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Index Page</title>
</head>
<body>
	<h3>Index Page</h3>
	<s:form action="helloWorld">
		<s:textfield label="Type any text here" name="name"></s:textfield>
		<s:submit value="Submit"></s:submit>
	</s:form>
</body>
</html>

The index.jsp page has a single form, text field and a button. When the user clicks on submit button, the form sends out the data to the action called helloWorld.

result.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@taglib prefix="s" uri="/struts-tags" %>    
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Result Page</title>
</head>
<body>
	<h3>Result Page</h3>
	<s:property value="name"/>
</body>
</html>

The result.jsp page simple prints out the value from name attribute.

HelloWorldAction.java

package com.jairrillo.struts2example;
 
import org.apache.struts2.config.ParentPackage;
import org.apache.struts2.config.Result;
 
import com.opensymphony.xwork2.ActionSupport;
 
@ParentPackage(value="struts-default")
@Result(name="success",value="result.jsp")
public class HelloWorldAction extends ActionSupport {
	private static final long serialVersionUID = 1L;
 
	private String name;
 
	public String execute() {
		name = name.toUpperCase();
		return SUCCESS;
	}
 
	//--- GETTERS AND SETTERS
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}    
}

Let’s analyse the code above together:

  • The execute method gets the name attribute and change its content to upper case.
  • The Action’s name is very important. As we’re not using the struts.xml file, the action’s name must follow a convention. As the form call the helloWorld.action, our action must be called HelloWorldAction.java.
  • The annotation @Result defines which page will be opened after the execute method
  • The annotation @ParentPackage defines which is the parent package from the current action. It’s the same than defined into struts.xml file

As you can see, in the code above, we created, implemented and also mapped the struts action. The question is: Where is the xml configuration? Answer: It doesn’t exist, very nice, huh?

Before run the application, we must setup another thing into web.xml file. How the struts will know where are the annotations? The need to inform him through the web.xml.

Into the web.xml file, add the following within FilterDispatcher.

    <filter>
        <filter-name>action2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
        <init-param>
        	<param-name>actionPackages</param-name>
        	<param-value>com.jairrillo.struts2example</param-value>
        </init-param>        
    </filter>

As you can see, we defined the package where the annotations are.

Running the application

Now, we can run our application. You can run it into any application server, like Tomcat, Jetty or IBM Websphere. The result should be a page like below:

Conclusion

As we can see in this topic, mapping an action through Struts 2 is very simple and productive. Besides the Action, we can use annotation for type conversion, validation and so on. You can download the application example here. Enjoy it.

I hope this topic be useful for anyone. If you have any comment or question, fell free to leave a message below.

  1. Mariano
    September 24th, 2009 at 13:11
    #1

    Hello. I was having a problem with annotations and your example was just what I needed. But the .zip is corrupted. Would fix it and upload it again? Thank you so much.

    Mariano

TOP