Java


Creating Web Components with Java Server Pages

Matt Youell

Scripting and Component-Based Development go hand in hand, but the key to effective scripting is to build components that are truly reusable.


JSP (Java Server Pages) is the Java alternative to other web development solutions such as Microsoft’s ASP (Active Server Pages) or Allaire’s ColdFusion. Like these other technologies, JSP allows program code to be integrated directly with HTML. This integration helps make JSP a very flexible system for controlling a web application’s presentation layer. This flexibility comes from the natural division of responsibilities: the Java code is responsible for generating and delivering data to the browser, while the HTML code is responsible for the formatting and presentation of that data. The sample JSP code in Listing 1 is a simple example of this division of responsibilities. (If you’re unfamiliar with JSP, this should become clear after reading the “JSP Basics” sidebar.)

Unfortunately, the flexibility that JSP provides is something of a double-edged sword. One of the biggest problems the JSP programmer faces is deciding whether the code belongs in the Java server page itself (the HTML with embedded JSP code) or in separate Java .class files that reside on the server. It is not uncommon to see even experienced JSP programmers creating complete applications entirely within the body of a single Java server page. This unfortunate approach seriously limits what a programmer can do when building an application.

One of the best ways to prevent this type of runaway coding is to use components. By using components, you can keep your JSP code short and sweet, and therefore more effective and less error prone. In this article I explain what a web component is, and then I walk through the steps of creating a Java component that can be used in JSP as well as Java servlets.

I will assume that you have some reasonable familiarity with Java. However, even if your only language is C++, you should still be able to understand most of what is going on. As with anything, hands-on trial and error is the best way to learn. So if you are interested in JSP, I seriously suggest that you get your hands on a JSP server and try running and tweaking the sample code that I present in this article.

Web Components

Component technology has been hyped in the press quite a bit lately. While most of the focus has been on components used in traditional applications, web applications can also benefit from component-based development. What makes a web component different from a regular component? The most significant difference is that web components must maintain their state throughout the run of a web "application." Traditional components have this ability built into their environment, but unfortunately the stateless, back-and-forth nature of the web means that web components have to make a special effort to hold onto their data.

The web components utilized in JSP are simply Java classes that sit on the server. Of course, not all classes are components. Most server-side classes are simply custom classes that are specific to the particular application at hand. Web components usually transcend any one application, and instead provide a more general solution to a problem. For this example I’ve chosen to create a generic GUI component that could appear in a wide range of applications. Many other components such as this can be built. Once you’ve had a taste of component construction using Java and JSP, you should be able to create components of your own and share them with others.

DatePulldown — A Simple JSP Component

I’ll start off by creating a simple GUI component called DatePulldown. It will display the month, day, and year as a set of HTML pulldowns. Listing 2 shows the Java code for the component, and Listing 3 shows the JSP code that uses the component. As you can see from Listing 3, very little Java code actually appears in the JSP file. This is as it should be, since you generally want to keep your JSP code as uncluttered as possible.

The Java class GregorianCalendar, provided in the java.util package, forms the core of this component. The GregorianCalendar class is handy for date storage and manipulation and I use it often. The setDate method of DatePulldown allows the date to be updated. Listing 3 shows how this function is called. First the servlet creates a DatePulldown object named Pulldown. Then it passes a Date object (also defined in java.util) into Pulldown’s setDate method. (A default-constructed Date object is initialized to the current date.)

The servlet then sends the HTML text to the browser. It replaces the <%=Pulldown%> JSP directive with the contents of the Pulldown object — more precisely, with the return value of Pulldown.toString. The DatePulldown.toString method generates HTML code to produce a date pulldown in the client’s browser. toString, in case you weren’t aware, is a method available in every Java object, which returns the string representation for that object. In this case, the string representation is the actual HTML that makes up the date pulldown component. This is handy, because toString is often called implicitly in Java. For instance, in Listing 3, the line <%=Pulldown%> is simpler and more user-friendly than <%=Pulldown.toString()%> would have been.

The code that creates the month and day pulldowns is pretty simple. However, the year pulldown is a little more complicated. After all, there are only 12 months in a year, and at most 31 days in a month, but the number of years that could be displayed is unlimited. For this reason I’ve created a 100-year window that starts with the current year and goes back 99 years. A more robust component might provide configuration methods to set that window, but for the purposes of this article I’ve chosen to keep things simple.

Remembering Input

So far so good. With the JSP implemented in Listings 2 and 3, it is possible to display a date on the fly. The next step is to allow the user to change the date and have that change persist between trips to the server. In order to do this, the Java servlet must be able to retrieve values from the web server that the user filled out in the pulldowns.

JSP provides a built-in Java object named request, which is available to the servlet, and contains the information needed. There are several ways the servlet could use the request object. In the first example I created a new Date object and passed that into the DatePulldown object. To follow that precedent, I could extract the month, day, and year values from request, create a new Date object based on those values, and call Pulldown.setDate with the new Date object. That, however, is messy and doesn’t contribute to the reusability of the DatePulldown class. Another way would be to create a new version of setDate that takes those month, day, and year values and creates the Date object internally. That is an improvement, but it’s still more work than I’d want to do.

Probably the best solution at this point is to take advantage of the Java Bean auto population feature in JSP. A Java Bean is basically just a Java class with traditional set/get accessor functions provided for its data members. These accessor functions must be named according to the convention getXXX/setXXX where XXX is the name of the data member to be accessed.

JSP provides a mechanism whereby the server automatically passes named values to Java Bean accessors that correspond to the value’s name. For example, suppose the user submits an HTML form that contains an item called firstName. If you create one or more Java Beans that provide a setFirstName method, the server can be made to find and call this method on all the objects that you specify.

To make this work with DatePulldown, I added the methods setMonth, setDay, and setMonth. Listing 4 shows the additional code for DatePulldown, and Listing 5 shows the new JSP that calls DatePulldown. Listing 5 contains a couple of new tags. The jsp:useBean tag tells the server to create a Java Bean of type DatePulldown named Pulldown. The setProperty tag tells the server to set all the properties (property="*") in the Pulldown object whose names match the items submitted in the HTML form. When the web browser submits the form containing the rendered DatePulldown, the values named month, day, and year are automatically passed into their corresponding methods. This prepares the DatePulldown component for rendering in exactly the same way that setDate did earlier.

Creating Multiple Date Pulldowns

If I only wanted to use one of these pulldown components per page, I’d stop here. But what happens if I do want to use more than one DatePulldown component per page? With the current implementation I’m out of luck because of the collisions that would happen between the month, day, and year value names for each pulldown. The conflicting values would be accepted on a first come, first served basis. That would result in all of the pulldowns displaying the exact same values. Clearly, that is unacceptable.

The best solution I have found involves giving each DatePulldown object a separate name, and prepending that name onto the value names generated for the form. So if I create a DatePulldown named Pulldown1, the resulting month value name will be named Pulldown1.month. Unfortunately, this approach will break the Java Bean auto population feature that I introduced in the last section. Losing the auto population feature means writing equivalent code to replace it. However, being able to use multiple DatePulldown instances in a particular page (for start and end dates, for example) would be very useful. So the tradeoff is probably worthwhile.

To implement this new scheme I add a new constructor that takes a component name as its only parameter. This allows multiple DatePulldowns to differentiate themselves from one another.

The only hitch at this point is encapsulating the code that reads and processes the form data for each DatePulldown. Happily, a simple solution presents itself in the form of the request object mentioned earlier. The request object is an instance of the Java class HttpServletRequest, and it can be used as a method parameter. The solution then, is to add an updated version of setDate that accepts an HttpServletRequest as a parameter. Listing 6 shows the new code that implements this functionality; Listing 7 shows the new code that uses it.

The new setDate method is smart enough to know when its associated pulldown has been named and when it hasn’t. It automatically reads the proper values based on its name. This allows multiple DatePulldowns to peacefully coexist, but it also allows single instances of DatePulldown to forgo the naming, for simplicity.

That’s as far as I’ll take this particular component. I started off with what was essentially a "one-off" class, and through a few simple changes that class was upgraded into a far more reusable component. There is certainly more work that could be done on this code, but it provides a good example of the basic functionality that you should expect from the components that you create.

Platform Info

JSP is still a relatively young technology, so let the programmer beware. While there is an official JSP standard, I don’t know of an implementation yet that is fully compliant. For the examples presented here I used the Jakarta Project’s Tomcat JSP server from the Apache Group. See http://jakarta.apache.org/. In addition I used the IBM Java2 JDK v1.3 on Redhat Linux v6.2.

Further Reading

When I first started working with JSP there were no books dedicated to the subject on the market. Since then a ton of books have hit the market. Personally, I found Wrox Press’s Professional JSP quite enlightening. And of course I would not touch a line of Java code without The Java Class Libraries, Second Edition, Volume 1, by Chan, Lee, and Kramer.

Matt Youell is a software engineer specializing in object-oriented web development. Visit him on the web at http://www.youell.com/matt.