Struts2 Introduction
— print (last updated: Nov 2, 2009) print

Select font size:
To run this sample project Eclipse, download and install the WAR file: StrutsIntro.war. In NetBeans, download the StrutsIntro.zip archive. These "Struts2 Essential" JAR files are needed for NetBeans:
commons-fileupload-1.2.1.jar
commons-io-1.4.jar
commons-logging-1.1.1.jar
freemarker-2.3.15.jar
ognl-2.7.3.jar
struts2-core-2.1.8.jar
xwork-core-2.1.6.jar

Java Web Frameworks

Struts2 is an enhancement of Struts (version 1), which is one of the older Java web frameworks. The 1.x series is what is currently used in NetBeans, but the most active development work is in the newer 2.x series. Struts 2 is based on the OpenSymphony WebWork Framework and represents the collaboration of Struts and WebWork developers.

Struts 2 framework is a MVC-style framework where the controller is expressed in terms of XML configuration files and Java "action" classes, and the view is JSP files using dedicated tags. According to the description on the Struts2 page, this framework provides three key components: Another framework which currently draws a lot of attention is Java Server Faces, also in 1.x and 2.x versions. The Apache MyFaces project provides a popular implementation and extension of JSF. The list of web frameworks goes well beyond Struts and Faces, including a fantastic variety of possibilities such as Barracuda, Calyxo, Chrysalis, Click, Cocoon, Grails, Maverick, Spring, Stripes, Rife, Shale, Seam, Tapestry, Thinwire, Turbine, Wicket, etc, etc.

Struts2 configuration

One key idea behind Struts2's MVC approach is that all URL requests must be associated with an action, as defined in a configuration file. In particular, all requests of a certain type must be filtered through a specialized handler scheme as specified by the basic web.xml configuration file:

web.xml
<web-app ...> <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>
The default extension used by Struts2 is ".action", i.e. any URL:
http://.../______.action
will "go through" the Struts2 processing. The processing associates the response with a certain Java class and a template output, often a single JSP file. This association mechanism can be made in a number of ways, but, perhaps the most common is through the file struts.xml located in the source folder:

struts.xml
<!DOCTYPE struts ...> <struts> <package name="default" extends="struts-default"> <action name="foo" class="action.Bar"> <result>/success.jsp</result> </action> <action name="sample" class="action.Bar"> <result>/sample.jsp</result> </action> <action name="testing" method="test" class="action.Bar"> <result name="failed">/failed.jsp</result> <result>/success.jsp</result> </action> </package> </struts>
The final ingredient in this example is the action class supporting the "result" JSP files. In this case it is

action.Bar
package action; public class Bar { private String info; public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } private String data = "initial data"; public String getData() { return data; } public void setData(String data) { this.data = data; } public String initial() { return "success"; } public String execute() { return "success"; } public String test() { if (info.trim().isEmpty()) return "failed"; else return "success"; } }

Sample Actions

We will explore a sample Struts2 form using these tags:
s:form
s:textfield
s:submit
The JSP welcome file illustrates two usages which we can compare

index.jsp
... <body> <a href="sample.jsp">sample.jsp</a><br /> <a href="sample.action">sample.action</a><br /> </body>
This uses the JSP "struts template" file:

sample.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib prefix="s" uri="/struts-tags"%> <!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>Sample Struts Form</title> </head> <body> <h2>sample.jsp</h2> <s:form action="foo"> <s:textfield name="info" label="Enter info" /> <s:textfield name="data" label="Enter data" /> <s:submit value="Press Me" /> <s:submit action="testing" value="Press Me Next" /> </s:form> </body> </html>
Observe the basic tag definition operation:
<%@ taglib prefix="s" uri="/struts-tags" %>
First activate this with the URL:
sample.jsp
Take a look at the underlying source code of the page to see the defaults that Struts does.

The "Press Me" button

On clicking this, the "foo" action is refers to this entry from struts.xml:
    <action name="foo" class="action.Bar">
      <result>/success.jsp</result>
    </action>
In this case, with no method defined, by default the String execute() method from action.Bar class is called, returning the success result string. The unnamed result tag within matches the success output and the success.jsp "template" is activated:

success.jsp
<body> <h2>success.jsp</h2> info: ${info} <br /> data: ${data} </body>
The two EL expressions correspond:
${info}      =  getInfo()
${data}      =  getData()
Struts2 employs what it calls the valueStack in that a bean representing an instantiation of the action.Bar class is "pushed on the stack" during the generation of the response, making info and data refer to this bean.

The setter methods, setInfo and setData, refer to the textfields with names info and data within the form, respectively. While generating the response for the action, these methods are invoked implicitly using the data entered into the respective fields.

Invoking sample.action

One sees different behavior when the second hyperlink is activated even though the same script, sample.jsp, is used. In this case the second action element is referenced:
    <action name="sample" class="action.Bar">
      <result>/sample.jsp</result>
    </action>
Again, the execute method is called, yielding a "success" result, but this time calling sample.jsp. The difference, easily noted, is that now that data textfield is initialized by virtue of the value of getData from in newly instatiated action.Bar object.

The "Press Me Next" button

The "Press Me Next" button specifies its own action:
<s:submit action="testing" value="Press Me Next" />
Pressing this invokes the testing action, referring to this entry in struts.xml:
 <action name="testing" method="test" class="action.Bar">
      <result name="failed">/failed.jsp</result>
      <result>/success.jsp</result>
 </action>
The method attribute indicates that the following, not the default execute method be called:
  public String test() {
    if (info.trim().isEmpty())
      return "failed";
    else
      return "success";
  }
The method can generate two possible result outcomes: "failed" or "success". The result tags within indicate that the failed.jsp script is be used in the former case and success.jsp in the latter case.


© Robert M. Kline