Introduction toThe Struts 2 Java Web Application Framework
Updated June 5, 2009.
My organization is using the Struts 2 Java web application framework to build new web applications. This introduction to Struts 2 is designed for Java web application developers who are not familiar with Struts 2. In this introduction I'll present a simple web application written using JavaServer Pages (JSP) and Java Servlets. Then I'll rewrite this application using Struts 2 to introduce Java web application developers to the Struts 2 framework.
Please note that this is just a brief introduction. Consult the references at the end of this article to find out how you can learn more about the Struts 2 framework. The capabilities of Struts 2 are quite extensive.
The Example Web Application
This simple web application is designed to allow a user to register for a prize drawing. The user visits a web page, completes a registration form, and then submits the form. The information the user provided is processed. If the user's data passes some simple validation, the user is sent to a thank you page that acknowledges his/her registration. If the user's data does not pass the validation, the user is returned to the registration page and an error message is displayed.
JSP and Servlet Version
You can download an archived Eclipse dynamic web project (reference 1) that you can import into Eclipse. A brief review of this code shows the application has register.jsp with a form for the user to complete. The form's action attribute is set to a Java Servlet (edu.ku.si.servlet.RegisterServlet.java).
The RegisterServlet class gets the user's entries for the form elements and creates an object of class Person. If the user's entries in the form on register.jsp pass some simple validation, the Person object's instance fields are set to the values the user entered in the form. The Person object is stored in the request scope and the user is forwarded on to the thankyou.jsp. The thankyou.jsp displays the information the user entered on the form, which is now stored in the Person object.
If the user's entries in the form on register.jsp do not pass the validation done by the RegisterServlet class then one or more error messages are stored in the errorMsg variable--which is placed in request scope--and the user is redirected back to the register.jsp. The register.jsp will display the contents of the errorMsg variable and show the user the form again with his/her previous entries.
Key Points About The JSP and Servlet Version.
- register.jsp - note how the error message is displayed and how the value attribute of the input tag is used to display any previous values entered for the form elements.
- RegisterServlet class - note how the doPost method has to get the user's form entries out of the request scope, convert the age form entry from a String to an int, and--if each form entry passes validation--set the appropriate instance field of class personBean (a Person object). If one or more of the user's form entries does not pass the validation test, then the errorMsg string is given an appropriate value and placed in the request scope. The user is then returned to register.jsp.
Get Struts 2
The current general availability release of Struts 2 is version 2.0.11 2.1.6 (reference 6). After unzipping the download you'll have a lib folder under the struts-2.1.6 folder. In the lib folder are all the jar files you'll need for the Struts 2 framework. Included in the download are documentation files ( struts-2.1.6\docs\index.html) and some example applications( struts-2.1.6\apps).
Create The Same Web Application Using Struts 2
You can download an archived Eclipse dynamic web project (reference 2) that you can import into Eclipse. When setting up a project that will use Struts 2 you'll need to include several jar files that contain the various classes that are part of the Struts 2 framework. Which jar files you'll need depends upon which parts of the Struts 2 framework you're using. For a basic Struts 2 web application you'll need to include these jar files:
- commons-logging-1.0.4.jar
- commons-fileupload-1.2.1.jar
- freemarker-2.3.13.jar
- ognl-2.6.11.jar
- struts2-core-2.1.6.jar
- xwork-2.1.2.jar
Create the Struts 2 version of register.jsp
Struts 2 comes with an extensive library of tags that you can use in your JSP pages. To use the Struts 2 tags in a JSP you need to code a taglib directive:
The Struts 2 tags generate HTML markup and can also display the value of variables.
In register.jsp of the JSP and Struts 2 version of the web application is this code:
<s:form action="Register">
<s:textfield name="personBean.firstName" label="First name" />
<s:textfield name="personBean.lastName" label="Last name" />
<s:textfield name="personBean.email" label ="Email"/>
<s:textfield name="personBean.age" label="Age" />
<s:submit/>
</s:form>
The Struts tags prefix is s (see the taglib directive above). The Struts 2 form tag is used to create the HTML markup for a form. It has many attributes that you can explore (see reference 8). I'm just using the action attribute to specify with Struts 2 action should be called when the form is submitted. I'll discuss actions later.
The Struts 2 textfield tag is used to create the HTML input markup. The name attribute specifies an instance variable of the Person class (represented by the personBean object). Using the name attribute enables Struts 2 to automatically populate the form field with the instance variable value if it exists and also to set the value of the instance variable to the value entered by the user when the form is submitted. So if the user types "Bruce" for the first name, Struts 2 will call the setFirstName method and pass "Bruce" to its parameter.
The label attribute is used to provide text next to the input field. There is much more you can do with the textfield tag, including using resource bundles to control the text displayed and in what language.
Since Struts 2 automatically populates the personBean object's instance variables with the values the user enters into the form fields, we don't need to use a Servlet to get the values out of request scope and do that work ourselves. Also note, Struts 2 will automatically convert the String entered for age (eg "22") to an int before calling the setAge method. Struts 2 can do a wide range of automatic data conversion from String to other data types (eg int, boolean, double) and convert back to String.
What Happens When The Form is Submitted?
In the JSP and Servlet example, when the form is submitted a Java Servlet class is called upon to process the user's input to the form, perform some basic validation, and either forward the user to the thankyou.jsp or return the user to the register.jsp (if the validation failed). In a Struts 2 web application, the form's action attribute specifies an alias to a Java class that extends the Struts 2 framework's ActionSupport class. In our JSP and Struts 2 example this class is Register.java in package edu.ku.si.action.
A class that extends the ActionSupport class must define an execute method that returns a String. The execute method will be called automatically when the form is submitted. But before the execute method is called, Struts 2 will populate the instance fields of the model object (in this case personBean of class Person) with the values entered by the user. To take advantage of this automatic instance field population, you just need to declare an object of the model class as an instance field in the class that extends ActionSupport (in our example that's class Register) and provide public set and get methods for that object.
Additionally, if the ActionSupport class has a validate method defined, Struts 2 will call that method when the form is submitted. If the validate method doesn't find any errors, then the execute method will be called. Check Register.java to examine the validate method. This method will get called automatically by the Struts 2 framework when the user submits the form on register.jsp.
execute Method
The execute method should contain the business logic. What does our application need to do when the user submits the form? Perhaps the application should store the user's input into a database table. Inside the execute method we can call upon other classes to do that work.
If everything has progressed correctly in executing the business logic, the execute method will return a String that equals "success." Since Register.java extends the ActionSupport class it has access to the SUCCESS final String constant. If there was a problem the execute method can return a different String value.
Depending on the value of the string returned by the execute method, the Struts 2 framework will forward the user to a specific JSP.
No More Servlets
If you examine the source code in the JSP and Struts 2 example you'll see that there is no Servlet class. The Struts 2 framework enables you to build web applications that follow the Model-View-Controller design pattern without having to use Servlets as controllers. Since Struts 2 accomplishes automatically much of what you use a Servlet for (getting user input out of request scope, updating a model, validation, forwarding user to a new view), you no longer need to create Servlet classes.
Wiring Everything Together
In the normal web.xml deployment descriptor file (see WebContent/WEB-INF/web.xml in the source code) we don't need all the plumbing to get a Servlet configured. What we do need in a Struts 2 application are a filter and filter-mapping nodes. Basically, these tell the application to filter all incoming requests to look for requests that target an action defined by Struts 2 in the struts.xml file.
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
The other critical xml file for wiring everything together is the struts.xml (see src/struts.xml). The code below is from the struts.xml file:
<action name="Register" class="edu.ku.si.action.Register">
<result>/thankyou.jsp</result>
<result name="input">/register.jsp</result>
</action>
Note the name attribute matches the value we gave the <s:form> tag's action attribute. When an incoming URL request has the value Register or Register.action then the Struts 2 framework will call the Register class. The two result child nodes determine which JSP is next viewed. If the execute method of the Register class returns "success" then the thankyou.jsp will be rendered. If the String returned is "input" then the user will be returned to the register.jsp.
Remember that the Register class has a validate method. If this method finds errors the user will be returned to the result with a name value of "input."
Mix and Match
Using the Struts 2 framework doesn't mean you cannot use Servlets, JSP Standard Tag Library (JSTL), or other Java web technologies.
What Next?
Struts 2 is a powerful web application framework that can automate much of the plumbing needed by a Java web application. This has been just a brief introduction to using the Struts 2 framework. The current version (2.0.11.2 2.1.6) has extensive capabilities that I've not mentioned including:
- Multiple methodologies for transferring data to objects
- Sophisticated workflow interceptors, including creating your own custom interceptors
- Extensive automated data conversion between types
- Large tag library
- A powerful expression language
- Alternatives to using JSP to render the view
- Integration with Spring and Hibernate
- Custom validation
- Support for internationalization
Of the references below, I recommend the Struts 2 in Action book. I've read this book several times and worked my way through its example code. You can read my review of the book on amazon. The Struts 2 in Action book is not perfect, but it does provide a very strong introduction to using Struts 2 along with some good example code.
References:
- JSP and Servlet Version of Registration Web Application (Archived MyEclipse Web Project)
- JSP and Struts 2 Version of Registration Web Application (Archived MyEclipse Web Project)
- The Apache Software Foundation, Struts
- Struts Key Technologies Primer
- Struts User Mailing List
- Struts 2 Version 2.1.6
- Struts 2 Documentation
- Struts 2 Version 2.1.6 Tag Reference
- Struts 2 in Action, Manning Publishing, 2008