We’ll start with the controller. It seems to make more sense to start there when talkingabout web applications. In fact, the MVC variant used in Struts is often referred to as a front controller MVC. This means that the controller is out front and is the first component to act in the process- ing. You can easily see this in figure 1.3. The controller’s job is to map requests to actions. In a web application, the incoming HTTP requests can be thought of as com- mands that the user issues to the application. One of the fundamental tasks of a web application is routing these requests to the appropriate set of actions that should be taken within the application itself. This controller’s job is like that of a traffic cop or air traffic controller. In some ways, this work is administrative; it’s certainly not part of your core business logic.
The role of the controller is played by the Struts 2 FilterDispatcher. This impor- tant object is a servlet filter that inspects each incoming request to determine which Struts 2 action should handle the request. The framework handles all of the controller work for you. You just need to inform the framework which request URLs map to which of your actions. You can do this with XML-based configuration files or Java annotations. We’ll demonstrate both of these methods in the next chapter.
NOTE Struts 2 goes a long way toward the goal of zero-configuration web applica- tions. Zero-configuration aims at deriving all of an application’s meta- data, such as which URL maps to which action, from convention rather than configuration. The use of Java annotations plays an important role in this zero-configuration scheme. While zero-configuration has not quite been achieved, you can currently use annotations and conventions to drastically reduce XML-based configuration.
Chapter 2’s HelloWorld application will demonstrate both the general architecture and deployment details of Struts 2 web applications.
Looking at figure 1.3, it’s easy to see that the model is implemented by the Struts 2 action component. But what exactly is the model? I find the model the most nebulous
of the MVC triad. In some ways, the model is a black box that contains the guts of the application. Everything else is just user interface and wiring. The model is the thing itself. In more technical terms, the model is the internal state of the application. This state is composed of both the data model and the business logic. From the high-level black box view, the data and the business logic merge together into the monolithic state of the application. For instance, if you are logging in to an application, both busi- ness logic and data from the database will be involved in the authentication process. Most likely, the business logic will provide an authentication method that will take the username and password and verify them against some persisted data from the data- base. In this case, the data and the business logic combine to form one of two states, “authenticated” or “unauthenticated.” Neither the data on its own, nor the business logic on its own, can produce these states.
Bearing all of this in mind, a Struts 2 action serves two roles. First, an action is an encapsulation of the calls to business logic into a single unit of work. Second, the action serves as a locus of data transfer. It is too early to go into details, but we’ll treat the topic in great depth during the course of this book. At this point, consider that an application has any number of actions to handle whatever set of commands it exposes to the client. As seen in figure 1.3, the controller, after receiving the request, must con- sult its mappings and determine which of these actions should handle the request. Once it finds the appropriate action, the controller hands over control of the request processing to the action by invoking it. This invocation process, conducted by the framework, will both prepare the necessary data and execute the action’s business logic. When the action completes its work, it’ll be time to render a view back to the user who submitted the request. Toward this end, an action, upon completing its work, will forward the result to the Struts 2 view component. Let’s consider the result now.
The view is the presentation component of the MVC pattern. Looking back at figure 1.3, we see that the result returns the page to the web browser. This page is the user interface that presents a representation of the application’s state to the user. These are com- monly JSP pages, Velocity templates, or some other presentation-layer technology. While there are many choices for the view, the role of the view is clear-cut: it translates the state of the application into a visual presentation with which the user can interact. With rich clients and Ajax applications increasingly complicating the details of the view, it becomes even more important to have clean MVC separation of concerns. Good MVC lays the groundwork for easily managing the most complex front end.
NOTE One of the interesting aspects of Struts 2 is how well its clean architecture paves the way for new technologies and techniques. The Struts 2 result component is a good demonstration of this. The result provides a clean encapsulation of handing off control of the processing to another object that will write the response to the client. This makes it easy for alternative responses, such as XML snippets or XSLT transformations, to be inte- grated into the framework.
If you look back to figure 1.3, you can see that the action is responsible for choosing which result will render the response. The action can choose from any number of results. Common choices are between results that represent the semantic outcomes of the action’s processing, such as “success” and “error.” Struts 2 provides out-of-the-box support for using most common view-layer technologies as results. These include JSP, Velocity, FreeMarker, and XSLT. Better yet, the clean structure of the architecture ensures that more result types can be built to handle new types of responses.
Since this favored MVC pattern has been around for decades, try visualizing what the MVC playing field would look like if the players were in fact nicely separated yet connectible. When I explain this to my students, I call it the Reese’s peanut butter cup principle. Is this tasty treat chocolate or peanut butter? After your first bite, you dis- cover it’s both! How could you use this peanut butter if all you wanted was a PBJ sand- wich? And so it goes with technology: how do you get all the richness you desire without actually “combining” the ingredients? Grab some sweets and continue read- ing to learn about Struts 2 and the framework request-processing factory.