ome suggest that the Struts framework has reached the point where its innovation and adoption will start declining. In fact, the Craig McClanahan, chief architect and author of Struts, has left the project for good, and he is actively urging current Struts users to migrate to newer Web frameworks.
Meanwhile, in the J2EE Web space, Spring MVC has gained steady adoption and Java developer attention. The highly popular Spring framework (with Spring MVC as its core component) is nicely designed, productive, and innovative, so many Struts users undoubtedly will investigate Spring MVC as a replacement framework for Struts.
This article helps developers who want to migrate their Struts applications to Spring MVC understand the logical mapping between the two frameworks and how to transform Struts applications into Spring MVC applications. Application developers with good Struts skills also will learn how key Struts concepts relate to Spring MVC concepts. Finally, this article should help architects understand and estimate the migration paths from Struts to Spring. To fully appreciate the subjects discussed, readers should have a working knowledge of the Struts framework.
The article is divided into two main parts:
- Logical mapping between the basic concepts of the Struts and Spring MVC frameworks
- Essential recommendations for migration alternatives
Logical Mapping: Similar Yet Different Frameworks
Struts and Spring are fundamentally similar implementations of the Model View Controller (MVC) architectural pattern. They are both intended primarily for the Model 2 type of development (see Related Resources in the left column), which is based on the core J2EE components servlet and JSP. Developers familiar with Struts should make the conceptual transition from one framework to the other rather easily. Both frameworks have clearly delineated boundaries for the components that serve the roles of the View, Controller, and, in the case of Spring, Model.
Similarities stop at the implementation level. The Struts design is based on concrete inheritance, meaning that each custom action has to be in an inheritance hierarchy of the Struts Action component. Because Spring controllers are interfaces, any component can play the role of the controller. This gives application designers more flexibility in the design of components.
At the framework component level, Struts requires use of Struts-specific objects, such as Form Beans (static or dynamic), Actions, Action Mappings, Action Forwards, and Request Processors. Spring MVC is more flexible, as all its major components are defined as interfaces.
Struts Is a Web Framework Only
Struts addresses only the presentation aspects of application development. On the other hand, Spring MVC is an integral part of the Spring framework, which fully integrates Spring with the rest of the frameworks that manage business components as well as other aspects of Spring enterprise development.
Now let’s look at the frameworks’ components in more detail.
Struts Actions Are Roughly Spring Controllers
In Struts, Actions are core “processing” objects of the framework. They play the role of controllers in the MVC pattern. Spring’s alternative to Struts Actions is the Controller interface. In other words, Controllers process user input and dispatch to view components in Spring. The most significant differences between the Struts Action and the Spring Controller are that Actions are abstract classes and Controllers are interfaces. In order to be configured as a Spring MVC controller, an object would need only to implement the following method:
ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
This design (also known as “design by interface”) minimizes the coupling between the application and the framework itself. Also, it gives the architect greater flexibility in the design of the Controllers. With this in mind, the simplest intermediary transition step from Struts to Spring is to rewrite Actions so they implement the Controller interfaces and reuse the existing code. This allows incremental removal of all the Struts dependencies while keeping the application operational.
Spring offers other Action alternatives as well. A number of framework-supplied Controller implementations match the most common Web application tasks. Some of the supplied Controllers match the more specialized Struts Actions with which you may be familiar. For instance, if you use DispatchActions, MultiActionControllers and the more elaborate AbstractWizardFormControllers will be helpful. About a dozen different Controller implementations come with Spring MVC, so it is well worth exploring their purposes and how they can replace your Struts mechanisms.
No Action Forms
One of the biggest and the most positive differences in the Spring framework is that it has no specialized ActionForm objects. The framework supports binding of HTTP form values directly into POJOs (Plain Old Java Objects). This feature greatly simplifies application maintenance by limiting the number of classes to create and maintain.
In this case, the migration would mean dropping form beans and using domain objects directly. However, this is not a mandatory step since you can still use Form Bean objects as a map between the form inputs and domain objects. In Spring MVC, special-purpose Controllers that extend the AbstractFormController implementation support form-backed beans. The custom subclasses of the AbstractFormController use these form-backed (Command) Beans as form objects. Again, no strict requirements define these beans. A Command object can be any subclass of the java.lang.Object.
ActionForwards vs. ModelAndView
In Struts ActionMapping, objects are pointers into presentation resources (Actions, JSPs, Tiles, HTML files, etc.). The closest component in Spring MVC to ActionMapping is the ModelAndView interface. Spring Controllers return implementations of the ModelAndView interface, which like a Controller can be custom implemented. Or, if appropriate, you can use the ModelAndView implementation supplied by Spring MVC.
As the name implies, ModelAndView objects have Model and View components. Model components contain the business object to be displayed via the View component. Depending on the scenario, ModelAndView implementations may not have any Model components included. They may simply forward into some form of an actual View component (JSP, XSLT, Tiles, HTML, XML, etc.). As with Controller implementations, I strongly recommend researching Spring MVC-supplied implementations of the Model and View interfaces and View Resolvers.
Custom JSP Tags
Spring MVC relies on the expressive power of the standard JSP tag libraries. Unlike Struts, Spring MVC does not supply separate tag libraries for HTML, logic, or bean processing. It offers only a small tag library (Spring) that enables binding of Command objects into Web forms. You should use standard template libraries (JSTL) for all other tasks.
If you use Commons Validator in Struts, you may be able to completely reuse it in Spring. Spring 1.2 does not officially support the Commons-based validation framework, but the “sandbox” version of Spring MVC supports the reuse of validation definitions written in Commons Validator markup (validator.xml and validation-rules.xml). In any case, do not throw away your XML files with validation declarations. They could be reusable in Spring.
Error and Validation Messages
More good news! Spring recognizes Struts message bundles in an identical format. In order to reuse your existing Message resources within Spring MVC, you just configure it as messageSource in the Spring MVC configuration file as follows:
Also, you would need to use it, like your Controllers, as a messageSource property in your Controller implementations. No other changes are required.
Spring MVC has its own version of the Request Processor/Action Servlet. It is DispatcherServlet, which is mapped to a group of URL expressions. To understand the concept of the Dispatcher Servlet, look at how Controllers are configured in Spring MVC.
As a Struts user, you are used to having at least one struts-config.xml file (or more if you are using modules) that holds all the forwards, action mappings, form definitions, and plug-in declarations. In Spring MVC, all the Web application-related controller declarations are configured as Spring Beans. One or more Dispatcher Controllers dispatch all requests for the Web resources to the appropriate Controllers. For instance, if you want to remap your “.do” application into a Spring MVC application, you register the following servlet mapping in the web.xml of your application (I am not actually recommending that you use .do as an extension. Leave “.do” as a Struts-only convention.):
... applicationDispatcher org.springframework.web.servlet.DispatcherServlet 1 applicationDispatcher *.do
Now you have a Spring configuration file (applicationDispatcher-servlet.xml) with your Spring MVC Controller declarations. Note the “-servlet.xml” suffix for the applicationDispatcher file. It is a Spring MVC convention that enables DispatcherServlet to auto-load Spring MVC mapping files.
Mapping Web actions to the appropriate controllers in Spring MVC is quite easy. It is done in the same “wiring” fashion as the rest of the Spring application. The following example shows how to forward URL expression /showCatalog.do into a Controller showCatalog:
The Controller showCatalog would be configured as another bean implemented by a class that implements Controller interfaces. In this example, showCatalog is nothing more than a simple forwarding controller that forwards URL requests to a ModelAndView component named catalog:
Transition Paths from Struts to Spring MVC
There are three approaches to migrating Struts applications to Spring MVC. Some architects will gradually migrate the applications; others will choose to completely abandon the Struts framework and perform a complete rewrite. The approaches are outlined below and ordered according to the migration’s completeness.
1. Spring Enabling of Struts Components
For those who want to migrate slowly, the first?and completely painless?step is to enable Struts Actions as Spring Beans. This is a simple process, and the Spring documentation details it well. It does not require any changes to the existing Struts code, but it enables Struts Controller components, Actions, to be treated as Spring Beans. In this process, Actions inherit the nature of the Spring Beans and, therefore, start looking a lot like Spring Controllers.
Slow and step-wise migration is possible with this process. Each Action could be replaced one at a time by the Spring Controllers without rewriting the application at once and interrupting the existing Web sequences.
2. Spring with Tiles
Another alternative, fully supported by the Spring framework, is to replace Struts Controllers and related components (Actions, Form Beans, etc.) with Spring MVC components while keeping Tiles as the pure “view” framework. Spring MVC does not have a specific alternative to Tiles, so architects may decide to keep their investments in Tiles and make them work through Spring MVC.
The one serious disadvantage of this approach is that you will effectively maintain two diverse Web frameworks in your Web application, which could result in a greater maintenance burden and training effort.
3. Complete Migration
Complete migration would mean total replacement of all the components of the Struts framework with Struts MVC. At the end of the process, no Struts-specific components would remain in the application.
Time to Spring Forward?
This article does not declare either framework better than the other. That is for you to decide, based on your understanding of the strengths and weaknesses of both and the architectural requirements at hand. In my opinion, Spring MVC has a brighter future, which is why I shared this guide for those who feel the same way and currently run large Struts-based applications. Those who are reasonably familiar with Struts and want to learn more about Spring in order to start adopting it also should find it useful.
Finally, one important feature of Spring that is not present in Struts and that is worth knowing is the upcoming Spring WebFlow framework. I recommend getting familiar with this flow-oriented framework as well if you plan to transition to Spring MVC.