|
|
|
|
JavaServer PagesBy Hans BergstenNovember 2000 1-56592-746-X, Order Number: 746X 572 pages, $39.95 |
Chapter 5
Generating Dynamic ContentIn this chapter, we develop a page for displaying the current date and time, and look at the JSP directive element and how to use JavaBeans in a JSP page along the way. Next, we look at how to process user input in your JSP pages and make sure it has the appropriate format. We also look at how you can convert special characters in the output, so they don't confuse the browser.
What Time Is It?
Recall from Chapter 3, JSP Overview, that a JSP page is just a regular HTML page with a few special elements. JSP pages should have the file extension .jsp, which tells the server that the page needs to be processed by the JSP container. Without this clue, the server is unable to distinguish a JSP page from any other type of file and sends it unprocessed to the browser.
When working with JSP pages, you really just need a regular text editor such as Notepad on Windows or Emacs on Unix. Appendix E, JSP Resource Reference, however, lists a number of tools that may make it easier for you, such as syntax-aware editors that color-code JSP and HTML elements. Some Interactive Development Environments (IDEs) include a small web container that allows you to easily execute and debug the page during development. There are also several web page authoring tools--the type of tools often used when developing regular HTML pages--that support JSP. I don't recommend that you use them initially; it's easier to learn how JSP works if you see the raw page elements before you use tools that hide them.
The first example JSP page, named date.jsp, is shown in Example 5-1.
Example 5-1: JSP Page Showing the Current Date and Time (date.jsp) <%@ page language="java" contentType="text/html" %><html><body bgcolor="white"><jsp:useBean id="clock" class="java.util.Date" />The current time at the server is:<ul><li>Date: <jsp:getProperty name="clock" property="date" /><li>Month: <jsp:getProperty name="clock" property="month" /><li>Year: <jsp:getProperty name="clock" property="year" /><li>Hours: <jsp:getProperty name="clock" property="hours" /><li>Minutes: <jsp:getProperty name="clock" property="minutes" /></ul></body></html>The date.jsp page displays the current date and time. We'll look at all the different pieces soon, but first let's run the example to see how it works. Assuming you have installed all book examples as described in Chapter 4, Setting Up the JSP Environment, first start the Tomcat server and load the http://localhost:8080/ora/ URL in a browser. You can then run Example 5-1 by clicking the "Current Date/Time example" link from the book examples main page, shown in Figure 5-1. You should see a result like the one shown in Figure 5-2.
Figure 5-1. JSP book examples main page
![]()
Figure 5-2. Current Date/Time JSP page example
![]()
Notice that the month seems to be off by one and the year is displayed as 100. That's because the
java.util.Dateclass we use here numbers months from 0 to 11, so January is 0, February is 1, and so on, and it reports year as the current year minus 1900. That's just the way this example works. As you will see later, there are much better ways to display dates.The page shown in Example 5-1 contains both regular HTML elements and JSP elements. The HTML elements are used as-is, defining the layout of the page. If you use the View Source function in your browser, you notice that none of the JSP elements are visible in the page source. That's because the JSP elements are processed by the server when the page is requested, and only the resulting output is sent to the browser. To see the unprocessed JSP page in a separate window, click on the source link for the date.jsp file in the book examples main page. The source link uses a special servlet to send the JSP page as-is to the browser instead of letting the server process it. This makes it easier for you to compare the source page and the processed result.
Let's look at each piece of Example 5-1 in detail.
Using JSP Directives
The first line in Example 5-1 is a JSP directive element. Directives are used to specify attributes of the page itself, primarily those that affect how the page is converted into a Java servlet. There are three JSP directives:
page,include, andtaglib. In this example, we're using only thepagedirective. We'll see the others later.JSP pages typically start with a
pagedirective that specifies the scripting language and the content type for the page:<%@ page language="java" contentType="text/html" %>A JSP directive element starts with a directive-start identifier (
<%@) followed by the directive name (e.g.,page) and directive attributes, and ends with%>. A directive contains one or more attribute name/value pairs (e.g.,language="java"). Note that JSP element and attribute names are case-sensitive, and in most cases the same is true for attribute values. For instance, thelanguageattribute value must bejava, notJava. All attribute values must also be enclosed in single or double quotes.The
pagedirective has many possible attributes. In Example 5-1, two of them are used:languageandcontentType.The
languageattribute specifies the scripting language used in the page. The JSP reference implementation (the Tomcat server) supports only Java as a scripting language.[1]javais also the default value for thelanguageattribute, but for clarity you may still want to specify it. Other JSP implementations support other languages besides Java, and hence allow other values for thelanguageattribute. For instance, both JRun (http://www.allaire.com) and Resin (http://www.caucho.com) support JavaScript in addition to Java.The
contentTypeattribute specifies the type of content the page produces. The most common values aretext/htmlfor HTML content andtext/plainfor preformatted, plain text. But you can also specify other types, such astext/xmlfor browsers that support XML ortext/vnd.wap.wmlfor devices like cellular phones and PDAs that have built-in Wireless Markup Language (WML) browsers. If the content generated by the page includes characters requiring a charset other than ISO-8859-1 (commonly known as Latin-1), you need to specify that charset with thecontentTypeattribute. We'll look at the details of charsets in Chapter 11, Internationalization.Using Template Text
Besides JSP elements, notice that the page shown in Example 5-1 contains mostly regular HTML:
...<html><body bgcolor="white">...The current time at the server is:<ul><li>Date: ...<li>Month: ...<li>Year: ...<li>Hours: ...<li>Minutes: ...</ul></body></html>In JSP parlance, this is called template text. Everything that's not a JSP element, such as a directive, action, or scripting element, is template text. Template text is sent to the browser as-is. This means you can use JSP to generate any type of text-based output, such as XML, WML, or even plain text. The JSP container doesn't care what the template text is.
Using JavaBeans
There is also some dynamic content in this example. Step back a moment and think about the type of dynamic content you see on the Web every day. Common examples might be a list of web sites matching a search criteria on a search engine site, the content of a shopping cart on an e-commerce site, a personalized news page, or messages on a bulletin board. Dynamic content is content generated by some server process, for instance the result of a database query. Before it is sent to the browser, the dynamic content needs to be combined with regular HTML elements into a page with the right layout, navigation bars, the company logo, and so forth. In a JSP page, the regular HTML is the template text described earlier. The result of the server processing--the dynamic content--is commonly represented by a JavaBeans component.
A JavaBeans component, or just a bean for short, is a Java class that follows certain coding conventions, so it can be used by tools as a component in a larger application. In this chapter, we discuss only how to use a bean, not how to develop one. (If you're a programmer and not already familiar with JavaBeans, you may want to skip ahead to Chapter 15, Developing JavaBeans for JSP, to learn about these coding conventions.) A bean is often used in JSP as the container for the dynamic content to be displayed by a web page. Typically, a bean represents something specific, such as a person, a product, or a shopping order. A bean is always created by a server process and given to the JSP page. The page then uses JSP elements to insert the bean's data into the HTML template text.
The type of element used to access a bean in a page is called a JSP action element. JSP action elements are executed when a JSP page is requested (this is called the request processing phase, as you may recall from Chapter 3). In other words, JSP actions represent dynamic actions that take place at runtime, as opposed to JSP directives, which are used only during the translation phase (when the JSP page is turned into Java servlet code). JSP defines a number of standard actions and also specifies how you can develop custom actions. For both standard and custom action elements, use the following notation:
<action_name attr1="value1" attr2="value2">action_body</action_name>Action elements, or tags as they are sometimes called,[2] are grouped into libraries (known as tag libraries). The action name is composed of two parts: a library prefix and the name of the action within the library, separated by a colon (i.e.,
jsp:useBean). All actions in the JSP standard library use the prefixjsp, while custom actions can use any prefix exceptjsp,jspx,java,javax,servlet,sun, orsunw. You specify input to the action through attribute/value pairs in the opening tag. The attribute names are case-sensitive, and the values must be enclosed in single or double quotes. For some actions, you can also enter data that the action should process in the action's body. It can be any text value, such as a SQL statement, or even other nested JSP action elements. You will see examples of action elements with a body later.Before you use a bean in a page, you must tell the JSP container which type of bean it is and associate it with a name. The first JSP action in Example 5-1,
<jsp:useBean>, is used for this purpose:<jsp:useBean id="clock" class="java.util.Date" />The
idattribute is used to give the bean a unique name. It must be a name that is a valid Java variable name: it must start with a letter and cannot contain special characters such as dots, plus signs, etc. Theclassattribute contains the fully qualified name of the bean's Java class. Here, the nameclockis associated with an instance of the classjava.util.Date. Note that we don't specify a body for this action. When you omit the body, you must end the opening tag with/>, as in this example. In this case, when the JSP container encounters this directive, there is no bean currently available with the nameclock, so the<jsp:useBean>action creates a bean as an instance of the specified class and makes it available to other actions in the same page. In Chapter 8, Sharing Data Between JSP Pages, Requests, and Users, you will see how<jsp:useBean>can also be used to locate a bean that has already been created.Incidentally, the
<jsp:useBean>action supports three additional attributes:scope,type, andbeanName. Thescopeattribute is described in detail in Chapter 8, and the other two attributes are covered in Appendix A, JSP Elements Syntax Reference. We don't need to worry about those attributes here.Accessing JavaBean Properties
The bean's data is represented by its properties. If you're a page author charged with developing a JSP page to display the content represented by a bean, you first need to know the names of all the bean's properties. This information should be available from the Java programmers on the team or from a third-party source. In this example, we use a standard Java class named
java.util.Dateas a bean with properties representing date and time information. Table 5-1 describes the properties used in this example. (If you're not a programmer, don't worry about the Java Type and Access columns at this point.)
Table 5-1: Properties for java.util.Date Property Name
Java Type
Access
Description
date
intread
The day of the month as a number between 1 and 31
hours
intread
The hour as a number between 0 (midnight) and 23
minutes
intread
The number of minutes past the hour as a number between 0 and 59
month
intread
The month as a number from 0 to 11
year
intread
The current year minus 1900
Once you have created a bean and given it a name, you can retrieve the values of the bean's properties in the response page with another JSP standard action,
<jsp:getProperty>. This action obtains the current value of a bean property and inserts it directly into the response body.To include the current
dateproperty value in the page, use the following tag:<jsp:getProperty name="clock" property="date" />The
nameattribute, set toclock, refers to the specific bean instance we defined with the<jsp:useBean>action previously. This action locates the bean and asks it for the value of the property specified by thepropertyattribute. As documented in Table 5-1, thedateproperty contains the day of the month as a number between 1 and 31. In Example 5-1, multiple<jsp:getProperty>actions are used to generate a list of all theclockbean's property values. The result is the page shown in Figure 5-2.Input and Output
User input is a necessity in modern web pages. Most dynamic web sites generate pages based on user input. Unfortunately, users seldom enter information in exactly the format you need, so before you can use such input, you probably want to validate it.
And it's not only the input format that's important. Web browsers are also picky about the format of the HTML you send them. For instance, when you generate an HTML form with values taken from a database, a name such as O'Reilly can cause problems. The single quote character after the O can fool the browser into believing that it's at the end of the string, so you end up with just an O in your form.
Using JavaBeans to Process Input
As we saw earlier, a bean is often used as a container for data, created by some server process, and used in a JSP page that displays the data. But a bean can also be used to capture user input. The captured data can then be processed by the bean itself or used as input to some other server component (e.g., a component that stores the data in a database or picks an appropriate banner ad to display). The nice thing about using a bean this way is that all information is in one bundle. Say you have a bean that can contain information about a person, and it captures the name, birth date, and email address as entered by the person on a web form. You can then pass this bean to another component, providing all the information about the user in one shot. Now, if you want to add more information about the user, you just add properties to the bean, instead of having to add parameters all over the place in your code. Another benefit of using a bean to capture user input is that the bean can encapsulate all the rules about its properties. Thus, a bean representing a person can make sure the
birthDateproperty is set to a valid date.Using a bean to capture and validate user input is one aspect of building a web application that's easy to maintain and extend as requirements change. But it's not the only option. If you're a page author and intend to use JSP to develop sites using components from third parties, you may wonder how you can capture and validate input without access to a Java programmer who can develop the beans. Don't worry; we'll see another alternative in Chapter 9, Database Access.
Processing and validating input can also be performed by a servlet instead of a JSP page. If you're a programmer, you'll find examples of this approach in Chapter 14, Combining Servlets and JSP. In this part of the book, however, we use JSP pages for all aspects of the applications so we can focus on JSP features. And one JSP feature makes it very easy to capture user input, so let's see how it's done.
Setting JavaBeans properties from user input
In this next example, we capture information about web site users. It could be the frontend to a newsletter subscription site, for instance. In order to send the users information that might interest them, we register the birth date, sex, and lucky number, along with the full name and email address, for each person that signs up for the service.
To capture and validate the user input, the example uses a bean named
com.ora.jsp.beans.userinfo.UserInfoBean, with the properties described in Table 5-2. If you're a programmer, you may want to skip ahead to peek at the source code for this bean class in Chapter 15.
Table 5-2: Properties for com.ora.jsp.beans.userinfo.UserInfoBean Property Name
Java Type
Access
Description
userName
Stringread/write
The user's full name
birthDate
Stringread/write
The user's birth date in the format yyyy-mm-dd (e.g.,
2000-07-07)emailAddr
Stringread/write
The user's email address in the format name@company.com
sex
Stringread/write
The user's sex (
maleorfemale)luckyNumber
Stringread/write
The user's lucky number (between 1 and 100)
valid
booleanread
trueif the current values of all properties are valid,falseotherwiseAs shown in the Access column, all properties except
validare read/write properties. This means that, in addition to using the bean's properties to generate output (like in Example 5-1), the property values can be set based on user input.The HTML form shown in Example 5-2 allows the user to enter information corresponding to the bean properties.
Example 5-2: An HTML Form that Sends User Input to a JSP Page (userinfo.html) <html><head><title>User Info Entry Form</title></head><body bgcolor="white"><form action="userinfo1.jsp" method="post"><table><tr><td>Name:</td><td><input type="text" name="userName" ></td></tr><tr><td>Birth Date:</td><td><input type="text" name="birthDate" ></td><td>(Use format yyyy-mm-dd)</td></tr><tr><td>Email Address:</td><td><input type="text" name="emailAddr" ></td><td>(Use format name@company.com)</td></tr><tr><td>Sex:</td><td><input type="text" name="sex" ></td><td>(Male or female)</td></tr><tr><td>Lucky number:</td><td><input type="text" name="luckyNumber" ></td><td>(A number between 1 and 100)</td></tr><tr><td colspan=2><input type="submit"></td></tr></table></form></body></html>This is a regular HTML page that presents a form with a number of fields, as shown in Figure 5-3. There are a few things worth mentioning here. First, notice that each input field has a
nameattribute with a value that corresponds to aUserInfoBeanproperty name. Matching the names lets us take advantage of a nice JSP feature that sets property values automatically, as you'll see shortly. Also note that theactionattribute of the form specifies that a JSP page, userinfo1.jsp, is invoked when the user clicks the Submit button. Figure 5-3 shows what the form looks like in a browser.
Figure 5-3. User input form
![]()
Example 5-3 shows the JSP page that is invoked when the user submits the form.
Example 5-3: A JSP Page that Validates User Input with a Bean (userinfo1.jsp) <%@ page language="java" contentType="text/html" %><html><body bgcolor="white"><jsp:useBeanid="userInfo"class="com.ora.jsp.beans.userinfo.UserInfoBean"><jsp:setProperty name="userInfo" property="*" /></jsp:useBean>The following information was saved:<ul><li>User Name: <jsp:getPropertyname="userInfo" property="userName" /><li>Birth Date: <jsp:getPropertyname="userInfo" property="birthDate" /><li>Email Address: <jsp:getPropertyname="userInfo" property="emailAddr" /><li>Sex: <jsp:getPropertyname="userInfo" property="sex" /><li>Lucky number: <jsp:getPropertyname="userInfo" property="luckyNumber" /></ul>The user input is valid: <jsp:getPropertyname="userInfo" property="valid" /></body></html>Almost at the top of Example 5-3, you see that a
<jsp:useBean>action is used to associate a name with the bean:<jsp:useBeanid="userInfo"class="com.ora.jsp.beans.userinfo.UserInfoBean"><jsp:setProperty name="userInfo" property="*" /></jsp:useBean>The
<jsp:useBean>action looks similar to the one in Example 5-1. Theidattribute specifies the name for the bean, and theclassattribute specifies the full name of the bean class. But here we also use a<jsp:setProperty>action as the body of the<jsp:useBean>action. You must therefore use the complete closing tag (</jsp:useBean>) to tell the JSP container where the action ends, instead of the shorthand notation used in Example 5-1. The body of the<jsp:useBean>action is executed only when a new bean is created. In this example, that's always the case, but as you will learn in Chapter 8, there are cases in which the bean already exists and the action is needed only to associate it with a name.Now let's take a closer look at the
<jsp:setProperty>action. As the name implies, this action is used to set the bean's property values. Like the<jsp:getProperty>action, it has anameattribute that must match theidattribute of a<jsp:useBean>action, and apropertyattribute that specifies which property to set.When a form is submitted, the form field values are sent as request parameters with the same names as the form field elements. In Example 5-3, note that an asterisk (
*) is used as thepropertyattribute value of the<jsp:setProperty>action. This means that all bean properties with names that match request parameters sent to the page are set automatically. That's why it's important that the form element names match the bean property names, as they do here. Automatically setting all matching properties is a great feature; if you define more properties for your bean, you can set them simply by adding new matching fields in the form that invokes the JSP page.Besides the
propertyattribute, the<jsp:setProperty>action has two more optional attributes:paramandvalue. If for some reason you can't use the same name for the parameters and the property names, you can use theparamattribute to set a bean property to the value of any request parameter:<jsp:setPropertyname="userInfo"property="userName"param="someOtherParam"/>Here, the
userNameproperty is set to the value of a request parameter namedsomeOtherParam.You can also explicitly set a bean property to a value that is not sent as a request parameter with the
valueattribute:<jsp:setPropertyname="userInfo"property="luckyNumber"value="13"/>Here, the
luckyNumberproperty is set to the value13. You typically use thevalueattribute only when you set the bean properties based on something other than user input, for instance values collected from a database.Validating user input
Never trust your users, at least not when it comes to entering information in the format you need. Often, you need to make sure the input is valid before you continue to process a request. A date, for instance, can be written in many different formats. If you don't live in the United States, you probably have had to fill out both an I-94 and a customs declaration form to be admitted by an immigration officer. You may have noticed that on one of the forms you need to write your birth date as yyyy/mm/dd and on the other you write it as mm/dd/yyyy. I always get it wrong.
Four of the
UserInfoBean's properties require a special format:birthDate,emailAddr,sex, andluckyNumber. A good place to make sure the input is valid is in the bean itself, which is exactly what theUserInfoBeandoes. With this bean, if you try to set any of the above properties to a value that isn't valid, the bean will leave the property unset. In addition, the bean has a true/false (Boolean) property namedvalid. This property has the valuefalseunless all other properties have been set to valid values.Let's see this in action. Example 5-3 displays the property values using the
<jsp:getProperty>action:<li>User Name: <jsp:getPropertyname="userInfo" property="userName" />Since a property is set only if the value is valid, no values are shown for improperly specified properties. Try it. Click on the "User Info 1 example" link under the Chapter 5 header in the book examples main page shown in Figure 5-1. Enter both valid and invalid values in the form and look at the result produced by the userinfo1.jsp page when you click Submit. A sample result is shown in Figure 5-4.
Figure 5-4. Output from userinfo1.jsp
![]()
Note that the Birth Date information is missing (at my age, you're not so eager to reveal your birth date), so the input is marked as invalid.
Keep On Doing It 'til You Get It Right
Okay, now you know how to set bean properties and you're aware that beans often validate their values. It would be nice if this technique could be used to display the same form over and over until all required input is correct. You can do that with just a few changes, as shown in Example 5-4, the userinfo2.jsp page.
Example 5-4: A JSP Page that Validates and Redisplays Until Correct (userinfo2.jsp) <%@ page language="java" contentType="text/html" %><html><head><title>User Info Entry Form</title></head><body bgcolor="white"><jsp:useBeanid="userInfo"class="com.ora.jsp.beans.userinfo.UserInfoBean"><jsp:setProperty name="userInfo" property="*" /></jsp:useBean><%-- Output list of values with invalid format, if any --%><font color="red"><jsp:getProperty name="userInfo" property="propertyStatusMsg" /></font><%-- Output form with submitted valid values --%><form action="userinfo2.jsp" method="post"><table><tr><td>Name:</td><td><input type="text" name="userName"value="<jsp:getPropertyname="userInfo"property="userName"/>"></td></tr><tr><td>Birth Date:</td><td><input type="text" name="birthDate"value="<jsp:getPropertyname="userInfo"property="birthDate"/>"></td><td>(Use format yyyy-mm-dd)</td></tr><tr><td>Email Address:</td><td><input type="text" name="emailAddr"value="<jsp:getPropertyname="userInfo"property="emailAddr"/>"></td><td>(Use format name@company.com)</td></tr><tr><td>Sex:</td><td><input type="text" name="sex"value="<jsp:getPropertyname="userInfo"property="sex"/>"></td><td>(Male or female)</td></tr><tr><td>Lucky number:</td><td><input type="text" name="luckyNumber"value="<jsp:getPropertyname="userInfo"property="luckyNumber"/>"></td><td>(A number between 1 and 100)</td></tr><tr><td colspan=2><input type="submit"></td></tr></table></form></body></html>Instead of using a static HTML page for the input form and a separate JSP page with the validation code, in this example we have combined them into a single JSP page. This page generates the form and provides an appropriate message based on whether or not the input is valid. The page also fills in the form with the valid values that have already been specified (if any) so the user needs to enter values only for missing or incorrect input.
Let's look at Example 5-4 from the top. The first thing to note is that the page generates a message using the
UserInfoBeanproperty namedpropertyStatusMsg.Here is the corresponding snippet:<%-- Output list of values with invalid format, if any --%><font color="red"><jsp:getProperty name="userInfo" property="propertyStatusMsg" /></font>The first line here is a JSP comment. Text between
<%--and--%>in a JSP page is treated as a comment and never appears in the result sent to the browser. For complex pages, it's always a good idea to include comments to explain things that are not obvious.The
propertyStatusMsgproperty can have three different values. If none of the properties have been set, the value is "Please enter values in all fields". If at least one value is missing or invalid, the message states "The following values are missing or invalid" and provides a list of the relevant properties. Finally, if all the values are valid, thepropertyStatusMsgis "Thanks for telling us about yourself!"Next we generate the form, filled out with all valid values. Here's the beginning of the form and the code for the
userNameproperty:<%-- Output form with submitted valid values --%><form action="userinfo2.jsp" method="post"><table><tr><td>Name:</td><td><input type="text" name="userName"value="<jsp:getPropertyname="userInfo"property="userName"/>"></td></tr>Most of this is plain HTML, which is treated as template text and passed on untouched to the browser. But note the use of a
<jsp:getProperty>action as the HTML<input>element'svalueattribute. This is how theuserNamefield in the form is filled in with the current value of theuserNamebean property. Also note how the form'sactionattribute points back to the JSP page itself.Try this out by clicking on the "User Info 2 example" link on the book examples page. Enter both valid and invalid values in the form and look at the results. In Chapter 8, we'll expand on this example and look at how you can move on to another page when all input is valid.
One item may look a bit strange to you: an element (
<jsp:getProperty>) is used as the value of another element's attribute (the<input>tag'svalueattribute). While this is not valid HTML syntax, it is valid JSP syntax. Remember that everything not recognized as a JSP element is treated as template text. Whether the template text is HTML, XML, WML, or just plain text doesn't matter. As far as the JSP container is concerned, the previous code is as valid as:any old template text <jsp:getPropertyname="userInfo"property="userName" /> more textWhen the JSP page is processed, the action element is replaced with the value of the bean's property. The resulting HTML sent to the browser is therefore valid.
Formatting HTML Output
If you enter a value containing double quotes in the Name field of the userinfo2.jsp page, it doesn't work right. For example, try "Prince, "the artist"" and you'll see what I mean. Only "Prince," appears in the Name field, and the Birth Date field is not shown at all. What's going on here?
A look at the HTML code generated by the JSP page using your browser's View Source function reveals what's wrong:
<table><tr><td>Name:</td><td><input type="text" name="userName"value="Prince, "the artist""></td></tr>In the JSP file, double quotes are used to enclose the value of the
<input>element'svalueattribute, so when the value itself includes a double quote, the browser gets confused. The first double quote in the value is interpreted as the end of the value. That's why you see only "Prince," in the field. Even worse, the rest of the value interferes with the interpretation of the rest of the form, causing the next input field to be ignored in most browsers.One solution to this problem would be to use single quotes around the values instead, since HTML accepts either single quotes or double quotes. But then you would have the same problem if the user enters a value that includes a single quote. Fortunately, there's a better way.
What's needed is special treatment of all characters that can cause HTML interpretation problems when we generate HTML from dynamic strings. One way to handle this is to let the bean take care of the special treatment. The
UserInfoBeancan do this through another set of properties:userNameFormatted,birthDateFormatted,emailAddrFormatted,sexFormatted, andluckyNumberFormatted.These are read-only properties that simply represent formatted versions of the corresponding real property values. The bean is designed so that when you use these property names, all troublesome characters in the real property values--such as single quotes, double quotes, less-than symbols, greater-than symbols, and ampersands--are converted to their corresponding HTML character entities (i.e.,
',",<,>, and&). The browser handles the converted values with no problem. If you're curious about the Java code for the formatted properties, it's described in Chapter 15. Example 5-5 shows a JSP page that uses the new properties.
Example 5-5: A JSP Page with Validation and Formatting Using a Bean (userinfo3.jsp) <%@ page language="java" contentType="text/html" %><html><head><title>User Info Entry Form</title></head><body bgcolor="white"><jsp:useBeanid="userInfo"class="com.ora.jsp.beans.userinfo.UserInfoBean"><jsp:setProperty name="userInfo" property="*" /></jsp:useBean><%-- Output list of values with invalid format, if any --%><font color="red"><jsp:getProperty name="userInfo" property="propertyStatusMsg" /></font><%-- Output form with submitted valid values --%><form action="userinfo2.jsp" method="post"><table><tr><td>Name:</td><td><input type="text" name="userName"value="<jsp:getPropertyname="userInfo"property="userNameFormatted"/>"></td></tr><tr><td>Birth Date:</td><td><input type="text" name="birthDate"value="<jsp:getPropertyname="userInfo"property="birthDateFormatted"/>"></td><td>(Use format yyyy-mm-dd)</td></tr><tr><td>Email Address:</td><td><input type="text" name="emailAddr"value="<jsp:getPropertyname="userInfo"property="emailAddrFormatted"/>"></td><td>(Use format name@company.com)</td></tr><tr><td>Sex:</td><td><input type="text" name="sex"value="<jsp:getPropertyname="userInfo"property="sexFormatted"/>"></td><td>(Male or female)</td></tr><tr><td>Lucky number:</td><td><input type="text" name="luckyNumber"value="<jsp:getPropertyname="userInfo"property="luckyNumberFormatted"/>"></td><td>(A number between 1 and 100)</td></tr><tr><td colspan=2><input type="submit"></td></tr></table></form></body></html>It's not always a good idea to have a bean handle this type of formatting, though. A bean is easier to reuse if it doesn't contain logic that is specific for one type of use, such as generating strings suitable for HTML. When we look at scripting elements and custom actions, we will revisit the subject of HTML formatting and look at other solutions to this problem.
Try the final version of this example by clicking on the "User Info 3 example" link. Now everything works fine, even if you happen to be Prince, "the artist."
1. In fact, Java is the only scripting language formally supported in the JSP specification, but the specification leaves room for other languages to be supported.
2. An element is actually represented by a start tag and an end tag, but the term "tag" is often used to refer to what's formally known as an element.
Back to: JavaServer Pages
© 2001, O'Reilly & Associates, Inc.
webmaster@oreilly.com