How do ActionMappings fit into the overall architechture of an application?

Ted Husted

Whither ActionMappings?

We write applications to do things for people. We might say, for example, that we want the appication to create a mail-merge job for us. Some developers call these top-level tasks "client stories". In practice, to do a big job like this, an application will need to take several smaller steps. We'll need to obtain the information from the user about which mail-merge job to create. We'll need to find the items to merge. We'll need to put the items together with a template, and we'll need to present the result back to the user. Some developers call these smaller tasks "use cases". To complete a client story, we usually chain several use cases together. A chain of use cases is sometimes called a workflow.

Before doing any thing for us, most applications wait to be asked. When we ask the application to do something, we usually need to provide a variety of details. If we ask the application to store a name and address, we need to provide the name and address to go along with the request.

HTML Forms

A web application collects such details through a HTML form. Under the hood, a HTML form submits a request to something called an "action". The action is a identifer that the web server can use to route the request to whatever software is suppose to handle it. The HTML specification does not much care what software is used to handle the request. It simply gives us a place where we can invoke the software we want to use.

Action Handlers

The simplest handler for an action is another HTML page. This doesn't accomplish much by itself, since a standard HTML page is static. Another simple way to handle an action is to install scripting software into your web server. This includes programs like Perl and Python. The server gives the request to the scripting software, and the scripting softare returns a response. The server sends the response back to the web browser (or other client).

Usually, the response will be in the form of another HTML page. Here, we might have a form action like action="/scripts/merge-form.pl". The HTML page returned by such a script may not exist as a separate file. The script can generate it "on the fly".

Server Pages

A more sophisticated way to handle an action is with a server-page. The software for handling the server-page is also installed into the web server. When a request for a certain type of page, say one matching the extension .jsp, comes along, the server passes the request to the server-page handler. The handler calls upon the page much like a script. The request acts as input to the server-page, and the page renders a response, just as scripting software would. Here, we might have a format action like action="/pages/merge-form.jsp".

Servlets

Java web applications can also use servlets. A servlet is a binary Java class. After installing the servlet handler (or "container"), you can register the servlet to handle requests that match a certain pattern. These might look like server pages (*.do), or like a sub-directory (/do/*). As with the other methods, the web server hands the request to the servlet, and the servlet hands back a response. (The web specification requires a response for every request.)

Most elements in a servlet class are there to support getting a request and returning a response. When Java developers write servlets, they will usually subclass a working servlet and add one relatively small method for doing some certain thing. Usually this certain thing corresponds to handling the input from a particular HTLM form. When this is true, a developer could register the servlet under a concrete identifier, rather than a pattern. This servlet would then handle one specific request (or "action").

Some servlets, like the Struts ActionServlet, let you put this specialized method into another Java class alogether. The ActionServlet is registed to handle all the requests matching a pattern. Each specific request (or "action") can be assigned to a Java class. Since these classes are most often called when a HTML form is submitted, Struts calls these "Action" classes.

ActionMappings

Struts keeps the list of action identifiers (or "paths") and their corresponding Action classes in a collection called the ActionMappings. Each entry in the collection is an ActionMapping object. You could create the ActionMappings collection using a Java class, but that's a lot of work. Struts can load the ActionMappings at startup time by reading a configuration file written in XML. (The servlet container uses a similar file to load the Java servlet classes.)

FormBeans

HTML forms often include several bits of information. A form that is adding a record to a database might include a dozen fields or more. The Java servlet container turns the request into a Java object which it passes along to the appropriate servlet. Struts in turn passes the request object to the Action class. You can look inside this object and get the names of every field submitted with the request and then also ask for the corresponding value. But this too is a lot of work.

Most Java application now use JavaBeans to represent fields like a name and address. A reasonable thing for a web developer to do is create a JavaBean with properties that match the attributes they expect a form to submit. If you create a JavaBean to match the HTML form, Struts can populate it for you automatically. Since this is the form that you submit with an action, Struts calls them ActionForms.

Validation

In practice, many HTML forms reuse the same set of fields. A developer can often create a single ActionForm that can be used with several different actions. To make the ActionForm's easier to reuse, Struts provides a FormBean class in the configuration file.

Web developers have to be very careful about the information that is passed to their application. It is very easy to for people to create a request that looks like it came from your form. But it could contain any sort of data whatsoever. The data may not be what your application expects. It is very important that web developers validate input before letting it into an application.

Accordingly, the Struts ActionForm includes a validate method. Developers can use this to test the input. If the input cannot be used, the method can return a list of messages. Struts then forwards the request, including the ActionForm object, back to an input page. The Struts tags can redisplay the data from the ActionForm, along with the messages, so the user can correct the errors and try again.

FormBean Names

The input page may contain more than one form. This means that Struts can't save the ActionForm under a constant name. To avoid collissions, each form (or action) should be able to have a name of its own. To help you manage an ActionForm's logical name, Struts provides a form-bean class in the configuration file. Each form-bean has a unique name and a property to indicate the ActionForm type. If two forms will appear on the same page, but can share the same ActionForm class, you can create two form-beans with different names but the same ActionForm type.

The (optional) Struts Validator uses the ActionForm attribute name to identify which validation to use with a request. When validate is called, the ActionServlet passes along the ActionMapping as part of the signature. The validator looks up its own form for that attribute and applies the appropriate validators.

Action Stories

In practice, the ActionMapping attribute, or form-bean name, is identifying the use-case underlying the Struts action. The form-bean exposes the set of fields the use-case needs. The validator-form confirms that all the fields are "present and accounted for". The Action class associated with the same attribute provides the link between the web presentation layer and your application's business logic.

If you are designing your application first, and then attaching it to Struts, a sound approach is to use the ActionMapping attribute to link your use case with the Struts ActionMapping and the corresonding HTML form.

To provide the best flexibility, the HTML form's action attribute is not directly linked to the ActionMapping's path property. It is tempting to consider using the same token for the ActionMapping attribute and path. But the path is used as an URI, which may have "business requirements" of its own. The URI paths might have to follow a certain pattern to fulfill security requirements. Since you do not want web requirements to trickle up to the business tier, it's best to use different tokens. You might start out with the pair being quite similar (like "/permit/search" for the path and "permit_search" for the name), but eventually you might need to change one but not the other.

Conclusion

When designing the presentation layer, consider form-beans and their attributes as an embodiment of your application's use-cases or stories. Rather than use these as "throw-away" names, link them into your overall architechture. This helps you visualize how an request progresses from the browser, through your controller, up to your module, and back again.

HTH, Ted.

--
Ted Husted,
Struts in Action

Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.