Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
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
Page 4 of 5
The processing logic within the controller page is straightforward. After the bean is instantiated, its validate() method is invoked. The validate() method has a two-pronged effect. If an error is encountered during the validation of any form input element, the validate() method not only resets the value of the corresponding bean property, but also sets an appropriate error message, which can
later be displayed for that input element.
If any of the required form elements cannot be successfully validated, the controller forwards the request to the JSP page retry.jsp (shown in Listing 5), allowing the user to make changes and resubmit the form. If there are no validation errors, the request is forwarded to success.jsp, shown in Listing 6.
Within retry.jsp, you first obtain a reference to the bean component that was previously instantiated and placed into the request by the controller. Also, since you don't want the user to reenter previously validated data, you refill the form elements by interrogating their previous state from the bean, like this:
<input type="text" name="firstName" value='<%=formHandler.getFirstName()%>' size=15 maxlength=20>
Any error message that may be applicable for the form input element is also retrieved and displayed via:
<font size=2 color=red>
<%=formHandler.getErrorMsg("firstName")%>
</font>
Also, observe the way I recreate the prior state of form input elements like radio buttons and checkboxes by using utility
methods such as isRbSelected(String s) and isCbSelected(String s), which were incorporated into the bean. Figure 2 shows the form generated by retry.jsp, which indicates some validation errors.
<jsp:useBean id="formHandler" class="foo.FormBean" scope="request"/>
<html>
<body>
<form action="process.jsp" method=post>
<center>
<table cellpadding=4 cellspacing=2 border=0>
<th bgcolor="#CCCCFF" colspan=2>
<font size=5>USER REGISTRATION</font>
<br>
<font size=1><sup>*</sup> Required Fields </font>
</th>
<tr bgcolor="#c8d8f8">
<td valign=top>
<B>First Name<sup>*</sup></B>
<br>
<input type="text" name="firstName"
value='<%=formHandler.getFirstName()%>' size=15 maxlength=20>
<br><font size=2
color=red><%=formHandler.getErrorMsg("firstName")%></font>
</td>
<td valign=top>
<B>Last Name<sup>*</sup></B>
<br>
<input type="text" name="lastName"
value='<%=formHandler.getLastName()%>' size=15 maxlength=20>
<br><font size=2
color=red><%=formHandler.getErrorMsg("lastName")%></font>
</td>
</tr>
<tr bgcolor="#c8d8f8">
<td valign=top>
<B>E-Mail<sup>*</sup></B>
<br>
<input type="text" name="email" value='<%=formHandler.getEmail()%>'
size=25 maxlength=125>
<br><font size=2 color=red><%=formHandler.getErrorMsg("email")%></font>
</td>
<td valign=top>
<B>Zip Code<sup>*</sup></B>
<br>
<input type="text" name="zip" value='<%=formHandler.getZip()%>' size=5
maxlength=5>
<br><font size=2 color=red><%=formHandler.getErrorMsg("zip")%></font>
</td>
</tr>
<tr bgcolor="#c8d8f8">
<td valign=top colspan=2>
<B>User Name<sup>*</sup></B>
<br>
<input type="text" name="userName" size=10
value='<%=formHandler.getUserName()%>' maxlength=10>
<br><font size=2
color=red><%=formHandler.getErrorMsg("userName")%></font>
</td>
</tr>
<tr bgcolor="#c8d8f8">
<td valign=top>
<B>Password<sup>*</sup></B>
<br>
<input type="password" name="password1" size=10
value='<%=formHandler.getPassword1()%>' maxlength=10>
<br><font size=2
color=red><%=formHandler.getErrorMsg("password1")%></font>
</td>
<td valign=top>
<B>Confirm Password<sup>*</sup></B>
<br>
<input type="password" name="password2" size=10
value='<%=formHandler.getPassword2()%>' maxlength=10>
<br><font size=2
color=red><%=formHandler.getErrorMsg("password2")%></font>
</td>
<br>
</tr>
<tr bgcolor="#c8d8f8">
<td colspan=2 valign=top>
<B>What music are you interested in?</B>
<br>
<input type="checkbox" name="faveMusic" value="Rock"
<%=formHandler.isCbSelected("Rock")%>>Rock
<input type="checkbox" name="faveMusic" value="Pop"
<%=formHandler.isCbSelected("Pop")%>>Pop
<input type="checkbox" name="faveMusic" value="Bluegrass"
<%=formHandler.isCbSelected("Bluegrass")%>>Bluegrass<br>
<input type="checkbox" name="faveMusic" value="Blues"
<%=formHandler.isCbSelected("Blues")%>>Blues
<input type="checkbox" name="faveMusic" value="Jazz"
<%=formHandler.isCbSelected("Jazz")%>>Jazz
<input type="checkbox" name="faveMusic" value="Country"
<%=formHandler.isCbSelected("Country")%>>Country<br>
</td>
</tr>
<tr bgcolor="#c8d8f8">
<td colspan=2 valign=top>
<B>Would you like to receive e-mail notifications on our special
sales?</B>
<br>
<input type="radio" name="notify" value="Yes"
<%=formHandler.isRbSelected("Yes")%>>Yes
<input type="radio" name="notify" value="No"
<%=formHandler.isRbSelected("No")%>> No
<br><br></td>
</tr>
<tr bgcolor="#c8d8f8">
<td colspan=2 align=center>
<input type="submit" value="Submit"> <input type="reset"
value="Reset">
</td>
</tr>
</table>
</center>
</form>
</body>
</html>
Because retry.jsp also posts data to process.jsp, the controller repeatedly instantiates the bean component and validates the form data until the user has entered valid data for all of the form elements.
Using a bean within a form in this way can be viewed as an implementation of the Memento design pattern. Memento is a behavioral pattern whose intent is to take a snapshot of a portion of an object's state so that the object can be restored to that state later, without violating its encapsulation. Because the bean is created and accessed within the boundary of the same request, the encapsulation of the memento is preserved intact.
As stated earlier, the controller forwards the request to success.jsp only after all of the submitted form data has been successfully
validated. Success.jsp in turn extracts the bean component from the request and confirms the registration to the client. Note
that while the scalar bean properties can be retrieved using a JSP expression or the <jsp:getProperty> tag, you still have to jump through a few hoops in order to display the indexed property type:
<%
String[] faveMusic = formHandler.getFaveMusic();
if (!faveMusic[0].equals("1")) {
out.println("<ul>");
for (int i=0; i<faveMusic.length; i++)
out.println("<li>"+faveMusic[i]);
out.println("</ul>");
} else out.println("Nothing was selected");
%>
In the future, you should not have to use scriptlet code to access indexed properties, but would instead use custom tags that support looping. Figure 3 shows the client on completion of a successful registration.
<jsp:useBean id="formHandler" class="foo.FormBean" scope="request"/>
<html>
<body>
<center>
<table cellpadding=4 cellspacing=2 border=0>
<th bgcolor="#CCCCFF" colspan=2>
<font size=5>USER REGISTRATION SUCCESSFUL!</font>
</th>
<font size=4>
<tr bgcolor="#c8d8f8">
<td valign=top>
<b>First Name</b>
<br>
<jsp:getProperty name="formHandler" property="firstName"/>
</td>
<td valign=top>
<b>Last Name</b>
<br>
<jsp:getProperty name="formHandler" property="lastName"/>
</td>
</tr>
<tr bgcolor="#c8d8f8">
<td valign=top>
<b>E-Mail</b>
<br>
<jsp:getProperty name="formHandler" property="email"/>
<br></td>
<td valign=top>
<b>Zip Code</b>
<br>
<jsp:getProperty name="formHandler" property="zip"/>
</td>
</tr>
<tr bgcolor="#c8d8f8">
<td valign=top colspan=2>
<b>User Name</b>
<br>
<jsp:getProperty name="formHandler" property="userName"/>
</td>
</tr>
<tr bgcolor="#c8d8f8">
<td colspan=2 valign=top>
<b>What music are you interested in?</b>
<br>
<%
String[] faveMusic = formHandler.getFaveMusic();
if (!faveMusic[0].equals("1")) {
out.println("<ul>");
for (int i=0; i<faveMusic.length; i++)
out.println("<li>"+faveMusic[i]);
out.println("</ul>");
} else out.println("Nothing was selected");
%>
</td>
</tr>
<tr bgcolor="#c8d8f8">
<td colspan=2 valign=top>
<b>Would you like to receive e-mail notifications on our special
sales?</b>
<br>
<jsp:getProperty name="formHandler" property="notify"/>
</td>
</tr>
</font>
</table>
</center>
</body>
</html>
Server-side Java: Read the whole series -archived on JavaWorld