Struts: View Actions

When describing Struts, people quickly use the examples of web forms.

Think of the following example: you have a form on which you fill in your data, and then click the submit button. The submit button posts an HTTP request to the web server — usually involving a URL such as “submitMyForm.do”. In Struts, an action (often called something like SubmitMyFormAction) gets invoked.

The action performs whatever work is necessary, and then forwards the request to a JSP that renders the results.

This is a pretty clear example of how to use Struts. In fact, I would go so far as to suggest that this is the motivating example behind the creation of Struts.

Submitting a web form, however, is not the only thing one does on web applications. Sometimes one wants to not only act on a page, but simply to view a page. And it’s this scenario that different Struts developers choose to handle very differently.

An Example

Take this example: suppose I’m building a web application that for a bank or financial institution. Part of my application includes a page that displays today’s mortgage rates. When someone clicks on a link to view my page, the application must first go check the database (or some other back-end system) and get the latest mortgage rates, and then render the mortgage rates on a pretty page (using a JavaServer Page) with a nice table in the middle.

This is a pretty typical requirement. Some pages require that certain pieces of data be gathered before displaying a page. But where to put that kind of code in a Struts-based web application? That’s the interesting point of discussion.

I’ve seen a few different approaches to this kind of example. The approaches can be broadly categorized into the following list:

  1. Some developers would have a scriptlet or custom tag in the JSP that gets the data just before rendering.
  2. Some developers would create a Struts action that doesn’t correspond with a web form — the action gets the mortgage rates, and then dispatches the request to the JSP to render the data
  3. In some extremely rare cases, someone might create a filter that sits in front of the JSP and has the responsibility to get the data prior to the JSP rendering.

Each of these approaches has certain benefits and disadvantages.

Personally, I avoid the first option. I dislike JSPs doing too much work. I don’t believe they should have “look-up” responsibilities; I’d rather just give them “render” responsibilities.

The second approach uses Struts actions in a way that I usually describe as a View Action. Later, I will discuss some of the reasons why the third approach can be attractive.

A Closer Look at View Actions

Here’s a pretty typical view action:

public class ViewMortgageRatesAction extends Action {

  public ActionForward execute(ActionMapping mapping,
      ActionForm actionForm, HttpServletRequest httpRequest,
      HttpServletResponse httpResponse) throws Exception {

    MortgageRates rates = retrieveTodaysMortgageRates();
    httpRequest.setAttribute("rates", rates);
    return mapping.findForward("success");
  }

  private MortgageRates retrieveTodaysMortgageRates() {
    ...
  }
}

This example illustrates some common features of View Actions, in particular, this overall pattern:

  1. get the data;
  2. put it into the request attribute (or session attribute); and
  3. forward to the associated JSP.

A View Action almost always has exactly one associated JSP. The JSP is configured in the struts-config.xml file:

<forward name="success"
    contextRelative="true"
    path="/mortgageRates.jsp"
    redirect="false" />

This pattern works fairly well for viewing a wide variety of pages, and I suspect that you can see this type of action in place in most Struts applications.

Many applications make a point of distinguishing between “submit” actions and “view” actions. Submit actions take in form data and process that data, and then dispatch the request to a view action for display.

It's only fair to share...
Share on FacebookGoogle+Tweet about this on TwitterShare on LinkedIn

Leave a Reply