How to map the Struts 2 action through Annotations (@Result)
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:
- Using the Struts 2 blank application
- Creating a new project and adding the required JARs yourself
- 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.

Brazilian guy, IT Specialist, Linux User, IBM Certified SOA Fundamentals, Rational Developer, Sun Certified Java Associate 1.0, Sun Certified Java Programmer 1.4, Sun Certified Web Component Developer 1.4 and Sun Certified Business Component Developer 5. Also Ruby and Python enthusiastic.
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