Section 4: Handling Request Parameters with Form Beans

Automatically Creating Java Objects to Represent Query Data

4.1 The Six Basic Steps: Recap 4.2 Example: Form and Result Beans
4.3 Example: Properties Files 4.4 Source Code
Struts Tutorial Table of Contents More Info

This section explains how to use form beans to represent the request parameters that are part of the form submission. It also shows how to use regular beans (as in regular MVC implemented with RequestDispatcher) to represent results.

4.1 The Six Basic Steps in Using Struts: Recap

With Struts, the normal processing flow is that a form submits data to a URL of the form blah.do. That address is mapped by struts-config.xml to an Action object, whose execute method handles the request. One of the arguments to execute is a form bean that is automatically created and whose properties are automatically populated with the incoming form data. The Action object then invokes business logic and data-access logic, placing the results in normal beans stored in request, session, or application scope. The Action uses mapping.findForward to return a condition, and the conditions are mapped by struts-config.xml to various JSP pages. The system forwards the request to the appropriate JSP page, where the bean:write tag is used to output properties of the form bean and results beans. Optionally, both the input form and the final JSP pages can use bean:message to output standard messages and labels as defined in a system properties file.

The previous section outlined the six basic steps needed to implement this process, and that section gave examples that illustrated four of the steps (the ones not involving beans). This section provides two additional examples that illustrate more complete versions of each of the steps. Here is a summary of the steps once beans are added to the process.

  1. Modify struts-config.xml.
    In addition to the action and forward elements used to specify the Action object and destination URLs, we use the form-bean element to declare form beans. We also add name and scope attributes to the action element to tie the form bean to the Action. Optionally, we add a message-resources element to declare a properties file containing standard messages, names, and labels.
  2. Define a form bean.
    This bean normally extends ActionForm and has properties (i.e., getter and setter methods) corresponding to each of the incoming request parameters. Alternatively, the bean can extend DynaActionForm, in which case it will contain a Map representing the request parameters.
  3. Create results beans.
    These are normal beans of the sort used in MVC when implemented directly with RequestDispatcher. That is, they represent the results of the business logic and data access code. These beans are stored in request, session, or application scope with the setAttribute method of HttpServletRequest, HttpSession, or ServletContext, just as in normal non-Struts applications.
  4. Create an Action object to handle requests.
    Rather than calling request.getParameter explicitly as in the previous examples, the execute method casts the ActionForm argument to the specific form bean class, then uses getter methods to access the properties of the object.
  5. Create form that invokes blah.do.
    This form can use the bean:message tag to output standard messages and text labels that are defined in the properties file that is declared with message-resources in struts-config.xml.
  6. Display results in JSP.
    The JSP page uses the bean:write tag to output properties of the form and result beans. It may also use the bean:message tag to output standard messages and text labels that are defined in the standard properties file.

4.2 Example: Form and Result Beans

In this example, the URL http://hostname/struts-test/actions/register3.do should be handled by the class RegisterAction3. Instead of reading form data explicitly with request.getParameter, the execute method of RegisterAction3 uses a bean that is automatically populated from the request data. As in the previous example, this method returns "success", "bad-address", or "bad-password", and these return values result in the JSP pages /WEB-INF/results/result3.jsp, /WEB-INF/results/bad-address3.jsp, and /WEB-INF/results/bad-password3.jsp, respectively. However, instead of displaying static HTML as before, these pages display specific values that RegisterAction3 creates and stores in beans.

There are three major new features in this example:


  1. Modify struts-config.xml.
  2. Define a form bean.
  3. Create results beans.
  4. Create an Action object to handle requests.
  5. Create form that invokes blah.do.
  6. Display results in JSP.
  7. Final results for this example.

  1. Modify struts-config.xml.
    Use WEB-INF/struts-config.xml to:
    Here is the resultant struts-config.xml (download the source code here).
    
          
    struts-config.xml (Excerpt)
    
    .. >
    
      
        
      
      
        ...
        name="userFormBean"
                scope="request">
          
          
          
         
      
    
    
  2. Define a form bean.
    A form bean is a Java object that will be automatically filled in with the incoming form parameters and passed to the execute method. A form bean has the following characteristics. For example, here is a form bean corresponding to the request parameters email and password (download the source code here).
    
          
    UserFormBean.java
    package coreservlets;
    
    import org.apache.struts.action.*;
    
    public class UserFormBean extends ActionForm {
      private String email = "Missing address";
      private String password = "Missing password";
    
      public String getEmail() {
        return(email);
      }
    
      public void setEmail(String email) {
        this.email = email;
      }
    
      public String getPassword() {
        return(password);
      }
    
      public void setPassword(String password) {
        this.password = password;
      }
    }
    
  3. Create results beans.
    The form bean represents the input data: the data that came from the HTML form. In most applications, the more important type of data is the result data: the data created by the business logic to represent the results of the computation or database lookup. In MVC parlance, that data is the "M" in MVC -- the Model.

    Results beans need to have getter and setter methods like normal JavaBeans, but need not extend any particular class or be declared in struts-config.xml. They are stored in request, session, or application scope with the setAttribute method of HttpServletRequest, HttpSession, or ServletContext, respectively. This is the same approach used with normal beans when the MVC architecture is implemented manually with RequestDispatcher.

    Following is a bean (SuggestionBean) that will be used to store suggested email addresses and passwords. When the user supplies an illegal email address or password, the bean will be populated by SuggestionUtils, stored in the request object, and then displayed in the error page that reports the illegal address or password. (Download the source code here.)
    
          
    SuggestionBean.java
    package coreservlets;
    
    public class SuggestionBean {
      private String email;
      private String password;
    
      public SuggestionBean(String email, String password) {
        this.email = email;
        this.password = password;
      }
      
      public String getEmail() {
        return(email);
      }
    
      public String getPassword() {
        return(password);
      }
    }
    
    
    SuggestionUtils.java
    package coreservlets;
    
    public class SuggestionUtils {
      private static String[] suggestedAddresses =
        { "[email protected]",
          "[email protected]",
          "[email protected]",
          "[email protected]" };
      private static String chars =
        "abcdefghijklmnopqrstuvwxyz0123456789#@$%^&*?!";
      
      public static SuggestionBean getSuggestionBean() {
        String address = randomString(suggestedAddresses);
        String password = randomString(chars, 8);
        return(new SuggestionBean(address, password));
      }
    
      public static int randomInt(int range) {
        return((int)(Math.random() * range)); 
      }
      
      public static String randomString(String[] strings) {
        return(strings[randomInt(strings.length)]);
      }
    
      public static char randomChar(String string) {
        return(string.charAt(randomInt(string.length())));
      }
    
      public static String randomString(String string,
                                        int length) {
        StringBuffer result = new StringBuffer();
        for(int i=0; i
        
  4. Create an Action object to handle requests.
    This example is similar to the previous one except that we do do not call request.getParameter explicitly. Instead, we extract the request parameters from the already populated form bean. Specifically, we take the ActionForm argument supplied to execute, cast it to UserFormBean (our concrete class that extends ActionForm), and then call getter methods on that bean. Also, we create a SuggestionBean and store it in request scope for later display in JSP. Here is the code (download the source code here).
    
          
    RegisterAction3.java
    package coreservlets;
    
    import javax.servlet.http.*;
    import org.apache.struts.action.*;
    
    public class RegisterAction3 extends Action {
      public ActionForward execute(ActionMapping mapping,
                                   ActionForm form,
                                   HttpServletRequest request,
                                   HttpServletResponse response)
          throws Exception {
        UserFormBean userBean = (UserFormBean)form;
        String email = userBean.getEmail();
        String password = userBean.getPassword();
        SuggestionBean suggestionBean =
          SuggestionUtils.getSuggestionBean();
        request.setAttribute("suggestionBean", suggestionBean);
        if ((email == null) ||
            (email.trim().length() 
        
  5. Create form that invokes blah.do.
    This form is just like the ones in the previous examples; we need an HTML form that invokes http://hostname/struts-test/actions/register3.do. We place the HTML form in the forms subdirectory and use a relative URL for the ACTION as follows (download the source code here).
    
          
    register3.jsp
    ..>
    
    New Account Registration
    
    

    New Account Registration

    ACTION="../actions/register3.do" METHOD="POST"> Email address:
    Password:
  6. Display results in JSP.
    As in the previous example, there are three possible JSP pages: one for a bad email address, one for a bad password, and one for success. However, in this example, the JSP pages need to output properties of the UserFormBean (representing the incoming form data) and the SuggestionBean (representing suggested email addresses and passwords). What are the alternatives for doing so? So, in this example we use bean:write. Before we do so, however, we have to import the "bean" tag library as follows.
    Here is the code (download the source code here).
          
    
          
    bad-address3.jsp
    ..>
    
    Illegal Email Address
    
    

    Illegal Email Address

    The address "" is not of the form username@hostname (e.g., ).

    Please try again.

    bad-password3.jsp
    ..>
    
    Illegal Password
    
    

    Illegal Password

    The password "" is too short; it must contain at least six characters. Here is a possible password: .

    Please try again.

    result3.jsp
    ..>
    
    Success
    
    

    You have registered successfully.

    • Email Address:
    • Password:
    (Version 3)
  7. Final Results.
    First, the HTML form is invoked with the URL http://localhost/struts-test/forms/register3.jsp, as follows.


    In the first case, this form is given "Bill Gates" as an email address and is submitted.


    The form's ACTION results in the URL http://localhost/struts-test/actions/register3.do. This address is mapped by struts-config.xml to the RegisterAction3 class, whose execute method is invoked. This method examines the email address, determines it is illegal because it lacks an "@" sign, and returns mapping.findForward with a value of "bad-address". That value is mapped by struts-config.xml to /WEB-INF/results/bad-address3.jsp, which is the final result displayed to the user for this input. Unlike the previous example, this JSP page shows both the illegal email address (taken from the form bean) and a suggested legal one (taken from the SuggestionBean).


    In the second case, the form is given a legal email address ([email protected]) but a password that is only five characters long (steve).


    The form's ACTION results in the URL http://localhost/struts-test/actions/register3.do. This address is mapped by struts-config.xml to the RegisterAction3 class, whose execute method is invoked. This method examines the password, determines it is too short, and returns mapping.findForward with a value of "bad-password". That value is mapped by struts-config.xml to /WEB-INF/results/bad-password3.jsp, which is the final result displayed to the user for this input. Unlike the previous example, this JSP page shows both the illegal email address (taken from the form bean) and a suggested legal one (taken from the SuggestionBean).


    In the third case, the form is given a legal email address and password. The form's ACTION results in the URL http://localhost/struts-test/actions/register3.do. This address is mapped by struts-config.xml to the RegisterAction3 class, whose execute method is invoked. This method finds no problem with either the email address or the password, so returns mapping.findForward with a value of "success". That value is mapped by struts-config.xml to /WEB-INF/results/result3.jsp, which is the final result displayed to the user for this input.

4.3 Example: Properties Files

This example is very similar to the previous one. However, some of the standard prompts and messages are taken from a properties file instead of being hardcoded in the JSP pages. To accomplish this, two new Struts features are used.

There are two advantages to using messages from properties files.


  1. Modify struts-config.xml.
  2. Define a form bean.
  3. Create results beans.
  4. Create an Action object to handle requests.
  5. Create form that invokes blah.do.
  6. Display results in JSP.
  7. Final results for this example.
  1. Modify struts-config.xml.
    The Action object and JSP URLs are declared with action and forward in the same manner as in the previous examples. In addition, the message-resources element is used to refer to a properties file as follows.
    
    
    The parameter attribute refers to the location of the properties file, relative to WEB-INF/classes and with the .properties file extension implied. So, for example, "resources.application" refers to WEB-INF/classes/resources/application.properties, and "foo.bar.baz" refers to WEB-INF/classes/foo/bar/baz.properties.

    The null attribute determines whether missing messages should be flagged. If the value is true (or the null attribute is omitted), references to nonexistent messages result in empty strings. If the value is false, references to nonexistent messages result in warning messages like ???keyName???. We recommend you use false, at least in the early stages of your development, so that you do not overlook typographical errors and incorrectly named messages.

    Here is the complete struts-config.xml file and the part of the properties file that is relevant to this example (download the source code here).
    
          
    struts-config.xml (Excerpt)
    
    .. >
    
      
        
      
      
        ...
        
          
          
          
         
      
      
      
                         
    
    
    
    application.properties (Excerpt)
    form.title=New Account Registration
    form.emailPrompt=Email Address
    form.passwordPrompt=Password
    form.buttonLabel=Sign Me Up!
    form.emailError=Illegal Email Address
    form.passwordError=Illegal Password
    form.passwordLength=six
    
  2. Define a form bean.
    This example uses the same UserFormBean as the previous example (download the source code here).
  3. Create results beans.
    This example uses the same SuggestionBean and SuggestionUtil classes as the previous example (download the source code here).
  4. Create an Action object to handle requests.
    This example uses the same RegisterAction3 class as the previous example (download the source code here). However, the struts-config.xml file associates the Action with a different incoming URL (register4.do instead of register3.do), and associates the return values with different JSP pages.
  5. Create form that invokes blah.do.
    Instead of directly listing the "Email Address" and "Password" prompts, the form takes them from the properties file. That way, if the prompts change (or if you have multiple versions in different languages), the prompts can be updated without modifying the actual JSP page. Also, as we will see later, the same prompts are used in the JSP page that shows the results, so extracting the prompts from the properties file limits changes to one location, even though the prompts are used in multiple locations.

    Here is the code (download the source code here).
    
          
    register4.jsp
    ..>
    
    
    <b><message key="form.title"></message></b>
    
    

    :
    :
    ">
  6. Display results in JSP.
    As in the previous example, there are three possible JSP pages: one for a bad email address, one for a bad password, and one for success. However, in addition to using bean:write to output bean properties, the JSP pages use bean:message to output standard prompts and messages taken from the properties file. Here is the code (download the source code here).
    
          
    bad-address4.jsp
    ..>
    
    
    <b><message key="form.emailError"></message></b>
    
    

    The address "" is not of the form username@hostname (e.g., ).

    Please try again.

    bad-password4.jsp
    ..>
    
    
    <b><message key="form.passwordError"></message></b>
    
    

    The password "" is too short; it must contain at least characters. Here is a possible password: .

    Please try again.

    result4.jsp
    ..>
    
    Success
    
    

    You have registered successfully.

    • :
    • :
    (Version 4)
  7. Final results.
    First, the HTML form that uses bean:message is invoked with the URL http://localhost/struts-test/forms/register4.jsp. Given the messages in WEB-INF/classes/resources/application.properties, this yields the following result.


    In the first case, this form is given "Bill Gates" as an email address and is submitted.


    The form's ACTION results in the URL http://localhost/struts-test/actions/register4.do. This address is mapped by struts-config.xml to the RegisterAction3 class, whose execute method is invoked. This method examines the email address, determines it is illegal because it lacks an "@" sign, and returns mapping.findForward with a value of "bad-address". That value is mapped by struts-config.xml to /WEB-INF/results/bad-address4.jsp, which is the final result displayed to the user for this input. Note that this example uses the same Action object (RegisterAction3) as the previous example, yet it uses a different incoming URL and different final JSP pages. This illustrates the flexibility that the struts-config.xml file gives over standard MVC where the JSP page addresses are hard-coded into the servlet code.

    Given the messages in WEB-INF/classes/resources/application.properties, this yields the following result.


    In the second case, the form is given a legal email address ([email protected]) but a password that is only five characters long (steve).


    The form's ACTION results in the URL http://localhost/struts-test/actions/register4.do. This address is mapped by struts-config.xml to the RegisterAction3 class, whose execute method is invoked. This method examines the password, determines it is too short, and returns mapping.findForward with a value of "bad-password". That value is mapped by struts-config.xml to /WEB-INF/results/bad-password4.jsp, which is the final result displayed to the user for this input. Given the messages in WEB-INF/classes/resources/application.properties, this yields the following result.


    In the third case, the form is given a legal email address and password. The form's ACTION results in the URL http://localhost/struts-test/actions/register4.do. This address is mapped by struts-config.xml to the RegisterAction3 class, whose execute method is invoked. This method finds no problem with either the email address or the password, so returns mapping.findForward with a value of "success". That value is mapped by struts-config.xml to /WEB-INF/results/result4.jsp, which is the final result displayed to the user for this input. Given the messages in WEB-INF/classes/resources/application.properties, this yields the following result.

4.4 Source Code for this Section

The following list gives the source code to all files described in this section, listed in the order that they appear. Note that the two example of this section are part of the same struts-test Web app as the examples of the previous section.

To download the code, right-click on the links and choose "Save Target As". Be sure to reproduce the same directory structure as given here. The easiest approach is to download and unjar the entire struts-test WAR file, but this takes some time since this WAR file includes the Struts JAR files in addition to the sample code.

Next section: Prepopulating and Redisplaying Input Forms

More Information

Servlet, JSP, and Struts Short Courses
Personally developed and taught by the author of Core Servlets & JSP, More Servlets & JSP, and this Jakarta Struts tutorial.
  • Programming with Servlet & JSP Technology. Fast-paced, hands-on course for developers who know Java but have little or no experience with servlets and JSP. Offered Nov 30-Dec 3 in Columbia, MD.
  • Advanced Servlet, JSP, & Struts Programming. Advanced hands-on course for developers with significant previous experience with servlets and JSP. Offered Dec 7-10 in Columbia, MD.
  • Applying Apache Struts. Advanced Struts-only course for those with significant previous JSP and servlet experience.
  • On-site JSP, Servlet, Struts, & JSF Training Courses. Customizable courses taught by Marty at your organization. Choose any combination of topics from Marty's Java, JSP, servlet, Struts, and JSF courses.
Contact Marty
Send email to [email protected] to report errors and omissions in this writeup or inquire about JSP/servlet/Struts training courses.
References
  • Apache Struts home page.
  • Apache Struts documentation.
  • JSP and servlet programming resources.
  • Servlet 2.3 and JSP 1.2 API.
  • Servlet 2.4 API.
  • JSP 2.0 API.
  • JSP, servlet, and Struts training and consulting
Apache Struts Books
  • Struts in Action: Building Web Applications with the Leading Java Framework.
  • Programming Jakarta Struts.
  • Professional Jakarta Struts.
Servlet & JSP Books
  • Core Servlets and JavaServer Pages, Second Edition.
  • Free online version of the First Edition of Core Servlets and JavaServer Pages. In PDF.
  • More Servlets and JavaServer Pages.