|
Related Reading
|
This excerpt is Chapter 5 from Java Server Pages, published in December 2000 by O'Reilly.
JSP is all about generating dynamic content: content that differs based on user input, time of day, the state of an external system, or any other runtime conditions. JSP provides you with lots of tools for generating this content. In this book, you will learn about all of them--standard actions, custom actions, JavaBeans, and scripting elements. Before we do that, however, let's start with a few simple examples to get a feel for how the basic JSP elements work.
In 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?
Using JSP Directives
Using JavaBeans
Input and Output
Setting JavaBean Properties From User Input
Keep On Doing It 'til You Get It Right
Formatting HTML Output
|
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|
|
|
|
Notice that the month seems to be off by one and the year is
displayed as 100. That's because the java.util.Date
class 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.
|
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, and taglib. In this example, we're using only the page directive. We'll see the others later.
JSP pages typically start with a page
directive 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, the language attribute value must be java, not Java. All attribute
values must also be enclosed in single or double quotes.
The page directive has many possible
attributes. In Example
5-1, two of them are used: language and contentType.
The language attribute specifies the
scripting language used in the page. The JSP reference implementation (the
Tomcat server) supports only Java as a scripting language.[1] java is also the default
value for the language attribute, but for clarity
you may still want to specify it. Other JSP implementations support other
languages besides Java, and hence allow other values for the language attribute. For instance, both JRun (http://www.allaire.com/) and
Resin (http://www.caucho.com/)
support JavaScript in addition to Java.
The contentType attribute specifies
the type of content the page produces. The most common values are text/html for HTML content and text/plain for preformatted, plain text. But you can also
specify other types, such as text/xml for browsers
that support XML or text/vnd.wap.wml for 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 the contentType
attribute. We'll look at the details of charsets in Chapter 11, Internationalization.
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.
|
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 prefix jsp, while custom
actions can use any prefix except jsp, jspx, java, javax, servlet, sun, or sunw. 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 id attribute 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. The class attribute contains the
fully qualified name of the bean's Java class. Here, the name clock is associated with an instance of the class java.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 name clock, 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, and beanName. The
scope attribute 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.
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.Date as 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 |
|
read |
The day of the month as a number between 1 and 31 |
|
hours |
|
read |
The hour as a number between 0 (midnight) and 23 |
|
minutes |
|
read |
The number of minutes past the hour as a number between 0 and 59 |
|
month |
|
read |
The month as a number from 0 to 11 |
|
year |
|
read |
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 date property
value in the page, use the following tag:
<jsp:getProperty name="clock" property="date" />
The name attribute, set to clock, 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 the property attribute. As documented
in Table 5-1, the date property 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 the clock bean's
property values. The result is the page shown in Figure 5-2.
|
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.
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 birthDate
property 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.
|
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 fcom.ora.jsp.beans.userinfo.UserInfoBean
|
Property Name |
Java Type |
Access |
Description |
|---|---|---|---|
|
userName |
|
read/write |
The user's full name |
|
birthDate |
|
read/write |
The user's birth date in the format yyyy-mm-dd (e.g., |
|
emailAddr |
|
read/write |
The user's email address in the format name@company.com |
|
sex |
|
read/write |
The user's sex ( |
|
luckyNumber |
|
read/write |
The user's lucky number (between 1 and 100) |
|
valid |
|
read |
|
As shown in the Access column, all properties except valid are 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 name attribute with a value that
corresponds to a UserInfoBean property 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 the action attribute 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.
|
|
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. The id attribute specifies the name for
the bean, and the class attribute 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 a name attribute that must match the id attribute of a <jsp:useBean> action, and a property attribute 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 the
property attribute 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 property attribute, the
<jsp:setProperty> action has two more
optional attributes: param and value. If for some reason you can't use the same name for
the parameters and the property names, you can use the param attribute to set a bean property to the value of
any request parameter:
<jsp:setPropertyname="userInfo"property="userName"param="someOtherParam"/>
Here, the userName property is set to
the value of a request parameter named someOtherParam.
You can also explicitly set a bean property to a value that is
not sent as a request parameter with the value
attribute:
<jsp:setPropertyname="userInfo"property="luckyNumber"value="13"/>
Here, the luckyNumber property is set
to the value 13. You typically use the value attribute only when you set the bean properties
based on something other than user input, for instance values collected from a
database.
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, and luckyNumber. A good place to make sure the input is valid
is in the bean itself, which is exactly what the UserInfoBean does. 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
named valid. This property has the value false unless 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.
|
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 UserInfoBean property named propertyStatusMsg. 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 propertyStatusMsg property 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, the propertyStatusMsg is "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 userName property:
<%-- 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's value
attribute. This is how the userName field in the
form is filled in with the current value of the userName bean property. Also note how the form's action attribute 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's value attribute). 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 text
When 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.
|
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's value attribute, 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 UserInfoBean can do this through another set of
properties: userNameFormatted, birthDateFormatted, emailAddrFormatted, sexFormatted, and luckyNumberFormatted.
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>
|
Related Reading
|
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.
Copyright © 2007 O'Reilly Media, Inc.