Using Struts 2 Convention and Annotation

Previously, I showed how to create a basic Struts 2 application from scratch. It used the struts.xml file to declare action classes and results. An alternative to that approach is afforded by the convention plugin. If you use that plugin, there is no need to declare action classes and results in struts.xml. System finds them based on certain conventions or rules. In addition, you can use annotations to further customize the rules.

Like the last tutorial, we will start from scratch. This will help someone absolutely new to Struts 2 to build a complete application without having to figure out dependencies and so on.

Downloading Struts 2 Library

Go to Struts download page.

image

Download the Struts library distribution as shown above. Unzip it somewhere. You will see all the JAR files in the lib folder.

image2

Create Eclipse Project

Make sure that you have Eclipse IDE for Java EE Developers installed and Tomcat is configured there.

Create a dynamic web project in Eclipse called StrutsHelloWorld.

Add the following JAR files to the WEB-INF/lib folder.

image

The convention plugin is enabled by adding the struts2-convention-plugin-2.3.16.3.jar JAR file. It requires asm-3.3.jar and asm-commons-3.3.jar as dependency.

Configure web.xml

Eclipse does not generate web.xml by default. Right click the project and select Java EE Tools > Generate Deployment Descriptor Stub.

Open WEB-INF/web.xml. Register Struts2 filter by adding these lines.

<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>

Save changes.

Develop the Action Class

The convention plugin looks for an action class in any package with struts, struts2, action or actions in the package name. The class itself must implement com.opensymphony.xwork2.Action or if its name must end with “Action”.

We will develop a simple action class that will take user’s name as input and print out a greeting message.

Create a class called com.example.actions.simple.HelloWorldAction. Add the following code:

public class HelloWorldAction {
 private String message;
 private String userName;
 
 public String execute() {
  setMessage("Hello " + getUserName());
 
  return "ok";
 }
 public String getMessage() {
  return message;
 }
 public void setMessage(String message) {
  this.message = message;
 }
 public String getUserName() {
  return userName;
 }
 public void setUserName(String userName) {
  this.userName = userName;
 }
}

Note a few important things:

  • The package name contains “actions” and the class name ends with Action.
  • The package name contains “simple” after “actions” and the name of the class minus “Action” is “HelloWorld”. Hence, the class is addressable via the URI /simple/hello-world. Details of these rules are explained very well in the official documentation.

Create the JSP Files

First, we will create the index.jsp page that will have a form where a user can enter her name.

image

In the WebContent folder, create a file called index.jsp. Add the following code:

<%@taglib uri="/struts-tags" prefix="s" %>

<html>
<body>
 <s:form action="simple/hello-world" >
 <s:textfield name="userName" label="User Name" />
 <s:submit/>
 </s:form>
</body>
</html>

Note that the action name is “simple/hello-world” which is the URI that addresses our HelloWorldAction class.

The <s:textfield> tag binds the input text field to the userName property of the action class.

Next, we will create a JSP that maps to the “ok” result returned by the execute() method. As per the rules used by the convention plugin, this file will be located as /WEB-INF/content/simple/hello-world-ok.jsp.

image

Create the JSP with the name and location shown above and add this code:

<%@taglib uri="/struts-tags" prefix="s" %>

<html>
<body>
 <h1><s:property value="message"/></h1>
</body>
</html>

This shows the message property of the action class.

Run the Application

Deploy the project in tomcat. Then run this URL:

http://localhost:8080/StrutsHelloWorld/

image

Enter a name in the text box and submit the form.

image

Make sure that you see the message.

Using Annotation

The convention plugin also allows annotation based programming. I find annotation leads to more natural style of programming. I don’t have to take my focus away from the Java code to an XML file. The downside is that it is not obvious which class and method implements an action URI. You will pretty much have to search the entire Java code base for a action URI. Anyway, let’s get started.

With annotation you can use almost any method name as an action handler. We will now change the HelloWorldAction class so that one method will display the form and another method will handle the form submission.

With annotation, the rules for the class name and package name remains the same. So, we will leave them unchanged.

First, change the execute() method like this:

@Action("/show-message")
public String showMessage() {
 setMessage("Hello " + getUserName());
 
 return "ok";
}

The @Action annotation makes the showMessage() method an action handler. The URI address for this action is “/show-message”. This will play a role in the naming of the JSP file mapped to the “ok” result. (Note: The class and package name no longer has any effect on the URI address.)

Add a new method that displays the form.

@Action("/show-form")
public String showForm() {
 return "start";
}

The URI address of this action handler method is “/show-form”.

Organize imports (Control+Shift+O). This will import the following package for @Action annotation:

import org.apache.struts2.convention.annotation.Action;

Save changes.

Now, let’s go ahead and move our focus to the JSP files. We already have the two files. We just need to rename them because the URI address of the actions have changed. The naming rule remains the same. It is “/WEB-INF/content/URIRESULT.jsp”. Rename the old files as follows:

Old file: /WEB-INF/content/index.jsp
New name:/WEB-INF/content/show-form-start.jsp

Old file:/WEB-INF/content/simple/hello-world-ok.jsp
New name:/WEB-INF/content/show-message-ok.jsp

image

Open show-form-start.jsp. Change the action URI in the <s:form> tag as follows.

<s:form action="/show-message" >

Save changes. Restart the server.

To test the new app, open a browser and enter the URL: http://localhost:8080/StrutsHelloWorld/show-form. Note the use of “/show-form” URI. This will invoke the showForm() method of HelloWorldAction class. The method returns a result of “start”. That causes Struts 2 to load /WEB-INF/content/show-form-start.jsp.

One advantage of loading the form using an action handler method is that you can pre-populate the input fields. To do so, simply initialize the action class properties that are mapped to the input fields. For example, in the showForm() method, initialize the userName property as follows:

@Action("/show-form")
public String showForm() {
 setUserName("Please enter a name");
 
 return "start";
}

Save changes. Wait for the application to be redeployed. Enter the URL http://localhost:8080/StrutsHelloWorld/show-form in the browser. This time the text field will be pre-populated as follows.

image

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s