Comparing the Struts 1 and Struts 2 Web Application Frameworks
Because the Struts web application framework was initially released at the beginning of this decade, developers have utilized it to construct many thousands of applications. Struts was, and still is, the most popular framework for building Java-based web applications. Though not without its flaws, Struts simplifies the construction of robust and maintainable web-based software. Today, there are probably twice as many applications using Struts than there are those using all other competing web frameworks combined. It is a tribute to Struts that so many succeeding frameworks, such as JSF (JavaServer Faces), borrowed many of their concepts directly from Struts. Struts is far from perfect, however, and in recent years developers have increasingly begun to turn to alternative solutions. To keep pace with developer demand, the Struts team released a major update to the framework; it's generally known as 'Struts 2'. The purpose of this article is to provide Struts 1 developers an overview of how Struts 2 works by looking at code. You will look at a sample application twice, once as a Struts 1 application, and then a second time as a Struts 2 application. You won't be able to cover everything, but it should be enough to get you started with Struts 2.
Struts was first released in 2001. Its primary contributor was Craig McClanahan. Prior to Struts, web applications were often a jumbled mix of Java scattered throughout JSP(JavaServer Pages) scriptlets, Java Servlets, and various Java classes. Applications produced in this haphazard manner were typically hard to test and even harder to maintain. Struts promoted an MVC (Model-View-Controller) architecture. With MVC, developers were able to produce more modular code that was flexible enough to allow an application to grow. The MVC style of development has stood the test of time and has proven itself to be a successful approach for constructing web applications. In the last several years, competing frameworks have emerged to address some of Struts' inadequacies. The Struts community began work on a next-generation Struts to address some of these problems. Another framework, called WebWork, had in the meantime gained some notoriety as a viable successor to Struts. Finally, the Struts team and WebWork decided to join forces; this union led to the emergence of Struts 2. Struts 2, in many respects, represents a significant improvement over Struts 1.
Struts 1 Walkthrough
As previously mentioned, this article will attempt to provide a comparison of Struts 1 and Struts 2 by comparing the code used to develop the same application with each framework. Some cursory knowledge of Struts 1 is assumed. The sample application you will create is called 'defect-tracker'. It allows users to record application defects and developers to record resolutions to those defects. The application is trivial with the most basic requirements, but it should provide sufficient opportunity to cover basic features common to most all web applications.
To begin a Struts 1 application, the first file you need is the web.xml configuration file. The web.xml file must be modified for Struts 1 so application URI requests can be routed to a Struts controller:
<servlet> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet </servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet> <!--Map Struts-related request to action--> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
URI requests matching the pattern '*.do' are received by the Struts ActionServlet. ActionServlet finds the Struts Action mapped to this request as specified in the struts-config.xml configuration file. The ActionServlet and Action objects comprise the 'controller' portion in the MVC architecture of a Struts application. To transport data between Struts Actions and the 'view', typically implemented as JSPs, Struts uses ActionForm objects. ActionForm objects represent the 'model'. When a user submits a form, the ActionForm, along with its data, is passed to the Action's execute method. The Action might validate the data, and then invoke any necessary business logic, which, ideally, will be encapsulated in another layer that is completely unaware of Struts. Once business logic executes, the Action transfers control to a view specified in one or more ActionForward objects, which are also configured in struts-config.xml. ActionForward entries represent the possible outcomes of an Action. They can be defined for each Action or globally to apply to all Actions. A glimpse of the struts-config file is provided below. The defect-tracker application has two sets of Actions and ActionForms. One set concerns the listing of existing defects. The second set addresses the manipulation of defect data, typically referred to as 'CRUD' ('Create-Update-Delete').
<global-forwards> <forward name="list" path="/list.do"/> </global-forwards> <form-beans> <form-bean name="listForm" type="web.DefectsListForm" /> <form-bean name="actionForm" type="web.DefectsActionForm" /> </form-beans> <action-mappings> <action path="/list" name="listForm" scope="request" type="web.DefectsList" validate="false"> <forward name="list" path="/pages/defects.jsp" /> </action> <action path="/action" name="actionForm" scope="request" type="web.DefectsAction" parameter="method" validate="false"> <forward name="edit" path="/pages/editDefect.jsp" /> <forward name="add" path="/pages/addDefect.jsp" /> <forward name="list" path="/list.do" redirect="true" /> </action> </action-mappings>
The last two entries in struts-config declare a properties file for displaying application messages and labels, and a separate configuration file to be used to add validation rules for the ActionForm objects in your application.
The defect-tracker application has a single domain object, Defect, that represents a system defect. Upon startup, the user is redirected to 'list.do', which maps to the DefectsList Action object's execute method that will retrieve a list of defects.