Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Server-side Java: Advanced form processing using JSP

Use the Memento design pattern with JavaServer Pages and JavaBeans

  • Print
  • Feedback

Page 5 of 5

Request chaining with JSPs and servlets

Although you saw the bean perform extensive state management and form validation, you may have noticed that the only validation performed on the userName element was to simply confirm that it was not blank! Typically, when adding new users to a database, your registration program has to first ensure that the username is unique and was not previously entered into the database. If you already have a database access servlet for this purpose, you may wonder how you can integrate it into the validation scenario discussed thus far. Well, the answer is, "Very easily!" You can simply forward the request to a servlet, just as you would to a JSP page, and continue processing. The servlet in turn can update the bean (or even add new beans to the request) and forward the request to another resource down the chain.

For example, you can make a minor change to the controller, process.jsp, so that it now forwards the request to a servlet on successful validation, instead of sending it to the success.jsp page as it did before:

<% if (formHandler.validate()) {
%>
  <jsp:forward page="/servlet/DBHandler"/>
<%
   }  else {
      // continue as before
   }
%>

Consider the servlet DBHandler shown in Listing 7.

Listing 7. A database access servlet

import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import foo.FormBean;
public class DBHandler extends HttpServlet {
  public void doPost (HttpServletRequest request, HttpServletResponse response) {
    try {
      FormBean f = (FormBean) request.getAttribute("formHandler"); 
      boolean userExists = false;
      //obtain a db connection and perform a db query 
      //ensuring that the username does not exist
      //set userExists=true if user is found in db
      //for a simple test, you can disallow the registration
      //of the username "rogerm" as:
      //if (f.getUserName().equals("rogerm")) userExists=true;
      if (userExists) {
        f.setErrors("userName","Duplicate User: Try a different username"); 
        getServletConfig().getServletContext().
          getRequestDispatcher("/jsp/forms/retry.jsp").
          forward(request, response);
      } else {
        //retrieve the bean properties and store them
        // into the database. 
        getServletConfig().getServletContext().
          getRequestDispatcher("/jsp/forms/success.jsp").
          forward(request, response);
      }
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
}

Since the bean is still present within the request scope, you can easily access it within the servlet, like this:

FormBean f = (FormBean) request.getAttribute ("formHandler");

Assuming that the servlet performs a database query and finds another user with the same username, the servlet can easily call a setter method within the bean to indicate the error condition, like this:

f.setErrors("userName","Duplicate User: Try a different username");

Once again, the servlet can then send the request along its merry way by means of a request dispatcher:

getServletConfig().getServletContext().
    getRequestDispatcher("/jsp/forms/retry.jsp").
    forward(request, response);

Figure 4 shows a situation in which the servlet, DBHandler, was able to locate a duplicate username.

Figure 4. Form displaying the duplicate user error generated by the servlet

If the servlet does not find a duplicate user within the database, it can update the database after accessing the registration information from the bean, and then forward the request to the success.jsp page confirming a successful registration.

Deploying the application

I will assume that you are using Sun's latest version of JavaServer Web Development Kit (JSWDK) to run the example. If you aren't, see the Resources section to find out where to get it. Assuming that the server is installed in \jswdk-1.0.1, its default location under Microsoft Windows, deploy the application files as follows:

  • Copy register.htm to \jswdk-1.0.1\webpages
  • Create the directory "forms" under \jswdk-1.0.1\examples\jsp
  • Copy process.jsp to \jswdk-1.0.1\examples\jsp\forms
  • Copy retry.jsp to \jswdk-1.0.1\examples\jsp\forms
  • Copy success.jsp to \jswdk-1.0.1\examples\jsp\forms
  • Copy forms.properties to \jswdk-1.0.1\examples\WEB-INF\jsp\beans
  • Copy FormBean.java to \jswdk-1.0.1\examples\WEB-INF\jsp\beans
  • Compile FormBean.java by typing javac -d . FormBean.java

This should create \jswdk-1.0.1\examples\WEB-INF\jsp\beans\foo\FormBean.class. If you are also testing the servlet, you will need to:

  • Update process.jsp to forward the request to the servlet as shown earlier
  • Update the classpath to include \jswdk-1.0.1\examples\WEB-INF\jsp\beans
  • Copy DBHandler.java to \jswdk-1.0.1\examples\WEB-INF\servlets
  • Compile DBHandler.java by typing javac DBHandler.java

Once your server has been started, you should be able to access the application using http://localhost:8080/register.htm as the URL.

Conclusion

While there are numerous established solutions for handling HTML forms, there are many compelling reasons why JSP makes a viable alternative to the more mainstream solutions. JSP, with its component bean-centric approach, may actually ease the processing of complex forms. The JSP container can also reduce the processing burden significantly by instantiating bean components and automatically parsing the request object. Following a bean-centric approach also makes it easier to implement design patterns like Memento, which can play a useful role in the form validation process. Using JSP for form handling does not preclude the use of servlets, as these complementary technologies can be effectively melded using techniques like request chaining.

About the author

Govind Seshadri is an Enterprise Java Guru for jGuru.com, and the author of Enterprise Java Computing -- Applications and Architecture from Cambridge University Press (1999). Learn more about Govind at jGuru.com.

Read more about Enterprise Java in JavaWorld's Enterprise Java section.

  • Print
  • Feedback