Struts2 and Model 2
July 1st, 2007 by Wes Wannemacher
Why Struts? |
Any seasoned web application developer will say that every time a new framework is released, there are bound to be zealots touting the merits of said framework. Typically, a language or framework evolves because the core designer becomes frustrated with the state of affairs of the reigning platforms. Web application development is difficult because developers need many unique skills to create an application or site that people want to use. Often times customers or users are attracted by good aesthetics and miss the advanced functionality. Conversely, when users adopt a system that is attractive to the eyes, these same users will eventually complain of the lack of features or the slowness with which some components load.
In particular, if your plan is to create an Internet-facing site and you are hoping to attract a broad base of regular users, it is very important to incorporate modern technologies like AJAX. To leverage AJAX, a web developer must have an understanding of the HTTP protocol, HTML, CSS JavaScript, and the application programming language of choice. It may not sound like much, being familiar with five technologies can not be terribly difficult, right? Developers who have worked with AJAX know that the technologies required to properly implement AJAX within an application are each very different from the others. To add to the broad base of expected knowledge, each browser has quirks that must be considered!
For a while in the technical community, the buzz on mailing lists and technical websites was to make sites simple, perform validation server-side, and never depend on JavaScript for anything important. Sites like Google would be cited as an example of the “right way” to develop a website. Then, Google blew everyone away with Google Maps. All of a sudden, everything we believed in was turned upside down. Here was an example of an advanced site that worked consistently in many different browsers. Google Maps did things that most of us would have never dreamed to try. Here was everyone’s example going against the grain! This led to what many people call the Web 2.0 revolution. Unfortunately, as time passed, the term Web 2.0 was overloaded with fluff and began creating hype reminiscent of the original dot-com boom.
During the old days of simple sites that did not exploit browser functionality, Struts 1.x became a popular framework for JSP/Servlet developers. Struts 1.x brought some nice features to web applications that would have taken a serious effort. People shied away from JavaScript because it was not considered portable, but the early Struts used some JavaScript and it was acceptable because it was small snippets tested across many browsers. To make purists happy, the validation could be configured to happen server-side. Struts 1.x also had an extensive tag library for honoring the validation and gluing other functionality into JSPs. Struts was also one of the first web application development frameworks that implemented the MVC design pattern. We will discuss MVC further in the MVC section.
Despite it’s features, Struts 1.x had some drawbacks that caused frustration for many developers. Among other things, one of the chief frustrations was the amount of required configuration. Another reason new projects had not been adopting Struts was the lack of support for advanced web technologies, AJAX in particular. Of the spin-offs created to attempt to address the drawbacks, the WebWork project became very popular. For the next generation Struts release, the two projects have merged. The result is Struts 2.x.
Struts2 is a very well-designed, highly extensible, modern framework. The original attractions to Struts are still incorporated, but vastly improved. There is a set of web application WAR files which can be downloaded from the Struts2 home page that can be bootstrapped to begin your project. These WAR files come in a few flavors, in particular, I prefer to start with struts-blank.war since a minimum set of dependencies are met and plug-ins can be added as needed. There is also a struts-showcase with example code of many of the new features.
Struts2 abstracts the details of the business logic objects away from the Servlet API. Because of this clean separation, much more time can be spent dealing with the core requirements of the project. This separation also allows modern development methods to be used (such as those commonly referred to as Extreme Programming). Since the core project requirements can easily be abstracted into a business layer which is not dependent on external frameworks, developers can start by writing unit tests and work backwards. This method is referred to as “Design by Contract” and allows developers to concentrate on meeting requirements first thus ensuring the satisfaction of the project owner. The new tag library for Struts2 is much more extensible than previous releases. The tags can be customized a number of different ways, for instance, to change the basic look and feel, stylesheet data can be added to make basic changes. The new tag library also has a few different “themes” to choose from which will drive the amount of markup created by the Struts2 tag. If the current theme in play is the “xhtml” theme, then a simple form without markup will generate a well-aligned and formatted table with labels on the left and input fields on the right. For those that want to control all aspects of the layout and markup, a “simple” theme exists which inserts no markup. The theme can be applied to the whole page, or individual elements. If only a small change, or a drastic change is required, the templates can be copied and modified. Struts2 will check for customized copies of tags before using the distributed tags which allows any of the Struts2 tags to be easily replaced with local copies. Struts2 also allows some of the common problems inherent in the HTTP protocol to be worked around. We often forget that HTTP is a stateless protocol. The JSP and Servlet API spoils us, there is a built-in session object and it is as reliable of a session object as in any web application platform. Because of this and some of the other stateful constructs, we often forget about the stateless nature of the communication between the web browser and the web server. When a developer forgets that HTTP is stateless, there will likely be two mistakes made. The first of these mistakes is to not code around form double submits. The other mistake is forgetting that users like to use the browser’s Back button. Struts2 has built-in support to deal with accidental double submissions using an interceptor called the Token interceptor combined with a token tag in your JSP form. Struts2 does not directly deal with the browser’s Back button, but Struts2 has incorporated the Dojo toolkit as it’s JavaScript framework. The Dojo toolkit is a well tested set of JavaScript components and modules that gracefully handle when a user tries to go Back. The Back button is really only troublesome when the page content has been altered with JavaScript. If page content was inserted with JavaScript, when the user presses back they may expect that the content is reverted to the previous view, and typically a browser will actually take the user back to the previous page. To make the user experience worse, the user will realize that going back a page was not what they expected so they will try to use the forward button. Going forward will only advance the view to the original state of the page which is most likely not what the user wanted. The Dojo components and modules have been written to appear to go back and forward the way a user would expect.
Another reason to consider Struts2 is that AJAX is now easily supported. One of the most common AJAX tasks is for a request to be sent to the server and have the response from the server inserted into a DIV element on the page without refreshing the entire page. In Struts2 this can easily be done with Struts2 tags (no JavaScript coding required). If the requirements are more complex, then the Dojo toolkit is exposed and available within your JSPs. The Dojo toolkit is one of the most advanced JavaScript frameworks available. Having built-in integration is a bonus to anyone that is familiar with Dojo.
Struts2 now has a plug-in interface that allows functionality to be added to your web application by simply adding the plug-in’s JAR file. There are existing plug-ins that allow integration with JSF, Spring, Guice, and JFreeChart to name a few. Although integration is helpful, the Struts2 framework is already quite feature-rich. Allowing these plug-ins create opportunities for developers to enhance Struts2 using features from other libraries. In the case of Spring, the Spring plug-in allows for classes to be referred to in the configuration files by their Spring bean id. It is a bit excessive to point to one configuration to another, but if you are already using Spring, then it makes sense to specify which classes are loaded in only one place.
Configuring Struts2 is much easier thanks to a few new features. The most helpful of these enhancements is the incorporation of very helpful defaults within configuration files. Another important enhancement is that the action is now the formbean (which will not make sense if you have not ever written code for Struts 1.x). Struts2 has fewer configuration files, and configuration files are much more concise than previous versions of Struts2. This makes learning the framework quite a bit easier than learning previous versions.
MVC (Model 2) |
Before diving into the actual coding, it is necessary to discuss Model 2 and MVC. In my career, I have come across Struts various times and until recently, it would normally be dismissed. Each time I encountered Struts, the first obstacle would always be this strange acronym that I have always had problems wrapping my mind around. What is MVC? Before discussing what MVC is, it may help to discuss what MVC is not, MVC is not an Java library or API. MVC is a “design pattern.” If you are unfamiliar with design patterns, design patterns are more like coding style than a library. MVC first appeared in Smalltalk-80 as a set of objects to aid in GUI programming. In Smalltalk, the View and the Controller were distinct objects that developers were expected to extend to allow the GUI to behave properly. For instance, a “Controller” would interpret input from a mouse or keyboard. Controllers in Smalltalk would have to cooperate to ensure that the proper controller is dealing with the triggered event. The controller would then perform the appropriate action on the “Model.” A model typically has no interface to adhere to, it is analogous to a “business object.” If the model is passive, then it is up to the view to find out about updates by querying the model for changes or expecting the controller to update the view when the view may need to be re-rendered. Views could also register with the model in cases where the model can change state without a controller knowing.
Although Smalltalk-80 is no longer commonly used, the MVC pattern has remained and periodically resurfaces as a maintainable and easy to use design pattern. In Smalltalk-80, views and controllers were concretely implemented, today in Java there is no concrete procedure for implementing a view, a controller or a model. It is up to the developer to create and maintain the distinction logically within the application code. The hardest part about implementing the MVC pattern is that there is no litmus test to tell you whether the application code properly implements the MVC pattern. Often developers confuse the practice of implementing the MVC pattern with using an MVC framework. Installing and developing a Struts web application does not necessarily mean that the project implements the MVC pattern. In the case of Struts, it is important to understand the difference. Although a developer can incorporate Struts into their web application project with no knowledge of MVC, it is not advisable to do so. As a framework, many of the architecture decisions are made based on the assumption that developers will adopt a design that follows the MVC pattern. Many times, especially when I first started with Struts, I found I was hung up trying to solve simple problems and eventually would find that I had to re-think the problem to come up with a solution that fit well into Struts. In almost every case, it would become clear that I was not using the MVC pattern.
Although Struts 1 rejuvenated developer interest in the MVC pattern, it has since been implemented in languages other than Java. The modern, evolved notion of MVC lends well to web application programming because the interaction between application server and web browser is much simpler than the complex event model in most modern GUIs. A web browser will send a request to the application server, the application server will then load a controller which will analyze the request and pick the appropriate action. The application code within the action will instruct the application server on how to generate a response (or view) and the action can pass information along to the view being generated. To know whether or not a project implements the MVC pattern correctly, it is easiest to verify whether the benefits of the MVC pattern are present in the project. The main benefit of implementing the MVC pattern is that Model objects should not directly depend on any of the other non-model components within the project. In traditional (non-MVC) projects, typically, data access or persistence code will find its way into business logic APIs or views, or business logic will be sprinkled in various locations (JSP code, SQL code, etc.). By separating the models (or business objects) from the view (or GUI) and controller (or action) code, it is easy to build an application around these business objects so that business logic is cleanly implemented separately from user interface, processing and persistence. Not only does this sound like good design, but the Java platform has facilities, like JUnit, to help developers easily maintain projects which are cleanly abstracted. JUnit has been adopted by many Open Source projects because easily repeatable unit tests help developers catch potential bugs much quicker than traditional debugging.
A few simple guidelines can help developers properly implement the MVC pattern.
- Before working on the UI, create a set of business objects. The business objects should all be JavaBeans (or at least conform to the JavaBean style as much as possible). These business objects should exist independently and unit tests should be created to verify their behavior.
- Create the persistence implementation independent of the business objects. There are some helpful tools like Hibernate that can help to create an easy-to-use and easy-to-maintain persistence layer. Unit tests for the persistence layer are optional.
- Once the core business objects are created and tested, work on the UI can begin. Up to this point, developers should not consider Struts because introducing Struts as a dependency is unnecessary.
This entry was posted on Sunday, July 1st, 2007 at 1:37 am and is filed under Opinion, Struts 2. You can follow any responses to this entry through the RSS 2.0 feed.
Spread the Word
del.icio.us Digg Furl Reddit StumbleUpon Technorati
You can leave a response, or trackback from your own site.
July 18th, 2007 at 2:47 am
Nice article. Thanks for your work.
Will reed the rest.
August 4th, 2007 at 4:19 pm
Good stuff, thanks. Companies should also organize their developer teams around MVC, not just design the Web systems with the patten.
Allows them to centralize the core services while retaining the agility they need in the LOB’s.
August 28th, 2007 at 11:24 pm
very well then… you just gave me a very neat overview of what should be expected of struts2 which of course im convinced and eager to start with.
September 6th, 2007 at 4:36 am
It seems like the first unofficial and much-much wanted resource for S2 is here!
Congrats and looking forward to much more.
We’ve just started with out first S2 project and the resources are not even S1 or WW2 people, so anything and everything out there is a big help and we’re hopeful of learning a lot more here. Cheers!
February 22nd, 2008 at 12:24 pm
Very nice, man! Very nice!
March 3rd, 2008 at 9:11 am
Great article. Thanks for your work.
April 20th, 2008 at 9:06 am
Good site I “Stumbledupon” it today and gave it a stumble for you.. looking forward to seeing what else you have..later
April 22nd, 2008 at 6:02 pm
[...] architecture. At this point, if you are unfamiliar with Model 2 and MVC, then check out this post. Struts2 handles requests in a way that is different than other frameworks. Although the request [...]
May 1st, 2008 at 10:04 am
Great writing. Thank you for your effort and sharing this information. Looking forward to reading more of your material!
March 21st, 2009 at 12:24 pm
This article can give me clear understanding of what Struts2 can work.
The explanation based on your experience is a great idea.
I just found this website.
And now I’m eagering to dig more.
September 29th, 2009 at 7:10 pm
Explained well. Thanks