Although Dreamweaver includes support for JSP tags, you can do a lot more with JSP when you start hand coding tags. The following sections cover creating JSP tags, handling form data, working with cookies, creating beans, and debugging your code.
The following section introduces you to scriptlets, declarations, expressions, and directives. This section will provide plenty of information to get you started.
I'll discuss JSP actions in the JavaBeans section. Although not all actions relate to JavaBeans, it's easier to explain them then.
Scriptlets
A scriptlet is any block of JSP code between <% opening and %> closing delimiters. Because JSP code is
processed
by a Web server, only the results of the JSP code are displayed, not the code itself.
To generate output, use the
out.print()
or
out.println()
methods
, like this:
<html>
<head>
<title>Welcome</title>
<body>
<h1>My First JSP</h1>
<%
out.print("This is my first JSP page.");
%>
TIP
The
out.print()
method doesn't put any line breaks into your HTML. If you need to generate a lot of HTML and you don't want it all in one big line when you view source, use the
out.println()
method instead.
Scriptlets aren't limited to generating output. You can also use them to declare values for different
variables
. In the following example, a series of scriptlets are used to format an HTML table:
<%
String vertAlignHdr = "bottom";
String vertAlignReg = "top";
int colSpan = 2;
int tblBorder = 1;
%>
<table border="<% out.print(tblBorder); %>">
<tr valign="<% out.print(vertAlignHdr); %>">
<th>Header 1</th>
<th>Header 2</th>
</tr>
<tr valign="<% out.print(vertAlignReg); %>">
<td colspan="<% out.print(colSpan); %>">content</td>
</tr>
</table>
Scriptlets are suitable for small amounts of code—when you start adding a lot of complexity, it becomes harder to debug. It also means that you're mixing your presentation layer (or GUI) with your business logic layer, which can mean extra work and heartache. At a certain level, working with JavaBeans is a much better way to go.
|
In Java, you can use if, while, for, and switch statements to test a condition or loop through a series of values.
You can use the if statement to check whether a condition is true or false and to run code, depending on which way the condition tests.
In the following example, the if statement tests to see if one number is higher than another: If it tests true, the code prints one message; if not, it prints another.
int number = 10;
int anothernumber = 5;
if (number > anothernumber) {
out.println(number + "is higher than " + anothernumber + ".
<br>");
}
else {
out.prinln(number + "is lower than " + anothernumber + ".
<br>");
}
You can use the for loop to execute a block of code a specific number of times. It's a handy tool for doing a lot of work.
The for loop starts out with a number that initializes the loop, an iterator that either
increases
or decreases the count, and sandwiched in between them, a test to control how many
loops
are made. Whenever the test returns true, the code block inside the for loop is executed.
In the following example, the for loop prints out the
numbers
0 through 9 followed by the HTML
<br>
tag.
int counter;
for (counter = 0; counter < 10; counter++) {
out.println(counter + "<br>");
}
A while loop is like a for loop, except it tests for a condition and continues to loop until the first time the condition is false.
You can rewrite the
preceding
for loop example as a while loop:
int counter = 0;
while (counter < 10) {
out.println(counter + "<br>");
}
A while loop is typically used to iterate over the entire set of records retrieved from a database table.
When an if statement gets too complex, you can usually use a switch statement to simplify the code's structure.
A switch statement allows you to execute a section of code depending on the value of an expression that you specify. These expressions are matched by case values.
In the following example, different blocks of code are executed depending on the incoming severity of a problem (as defined by the severity test):
switch (severity) {
case 1:
out.println("show stopper<br>");
break;
case 2:
out.println("serious problem<br>");
break;
case 3:
out.println("minor problem<br>");
break;
case 4:
out.prinln("inconvenience<br>");
break;
}
The break statement at the end of each case value
prevents
the switch statement from testing all remaining case values.
|
Declarations
A declaration is a scripting element that enables you to declare variables and methods you'll use on a JSP page. You have to define all methods and variables before you can use them. Declarations begin with a <%! delimiter and end with a %>
delimiter
.
NOTE
Although you can declare variables inside a scriptlet (as seen in the previous section), the preferred method is to use a declaration.
In the following example, I declare the values of various variables:
<%!
String name = "Tom";
int age = 31;
String birthday = "June 5";
%>
After these variables have been assigned values, I can refer to them elsewhere in my JSP page:
<p>Hello, my name is <% out.print(name); %>.
<p>I'm <% out.print(age); %> and my birthday is <% out.print(birthday); %>.
Expressions
Simply put, an expression is a scripting element that allows you to generate output on a JSP page. Although a lot of what you can do with expressions can be done with scriptlets, expressions don't require as much coding. Instead of beginning an expression with a
<%
delimiter, you'd use a
<%=
delimiter. The = part is shorthand for
out.print()
or
out.println()
.
In the following example, I set a variable inside a declaration and then use an expression to generate output:
<%!
String mySite = "World of JSP";
%>
<h1>Welcome to the <%= mySite %>!</h1>
Directives
Directives provide information about a JSP page to the software that's processing the page. In JSP, there are three directives:
-
Page, which enables you to specify configuration information about the page.
-
Taglib, which enables you to define a tag library and a prefix that can be used to reference the custom tags.
-
Include, which enables you to include a file inside a JSP file.
A directive must be contained between a
<%@
opening delimiter and a
%>
closing delimiter.
Here's an example of an include directive:
<%@ include file="/jsp/footer.html" %>
NOTE
Any JSP commands in an included file will not be processed by the Web server. To reuse Java code, start using JavaBeans (see the section on JavaBeans a little later in this chapter).
Here's an example of a taglib directive:
<%@ taglib uri="http://www.mysite.com/tags/xyz" prefix="xyz">
Here's an example of a page directive:
<%@ page autoFlush="true" contentType="text/plain" %>
NOTE
Because the page directive has so many complex parameters, it's probably a good idea to use Macromedia MX's built-in Tag Chooser to help you build the tag.
Handling Form Data
One of the most common
tasks
you'll undertake in JSP programming is handling form data. Whenever a
user
logs in to a site, answers a survey, or handles more complex tasks such as entering information into a database, you'll need to process that form data and do something with it.
To handle data from a form, you must first create a form. The action property of the
<form>
tag must point to a JSP page that will process the form. Each of the form elements (text fields, check boxes, and so on) has a name assigned to it, and the JSP processing page can refer to those elements by name.
In the following example, a simple form is created to gather a person's name and age:
<html>
<title>Form</title>
<body>
<form action="/scripts/processform.jsp" method="post">
Enter your name: <input type="text" name="name"><br>
Enter your age: <input type="text" name="age"><br>
<input type="submit" name="Submit">
</form>
</body>
</html>
Save the file as
form.html
and place it in your Web server's docroot.
Now that you have a form, create the processform.jsp page:
-
Add the necessary information to the page for context:
<html>
<title>Thank you for filling out the form</title>
<body>
<p>Thank you for filling out the form.
-
Next
, use the
getParameter()
method of the request object to gather information on each form element.
You said your name is: <% request.getParameter("name") %>.<br>
You said your age is: <% request.getParameter("age") %>.<br>
</body>
</html>
-
Save the file as processform.jsp in your Web server's docroot and view the form.html page. After you fill in the form and click Submit, the JSP page should process the form and display the results.
Cookies
Web servers run on the HTTP protocol, which is stateless—in other words, a Web server doesn't know who you are, nor can it distinguish one visitor from another. It just handles
requests
and serves up pages and other files.
Although this makes for an easy-to-implement communication protocol, it also means that it becomes harder to provide customized content for
visitors
, to gather and remember their preferences (such as background
color
, font
size
, and other information), and to allow
convenient
bypass of a login screen ("remember me").
Each cookie in JSP can be created with the cookie object. You can use this object to create keys and values for any cookie. For example, suppose that you want to store a message on a visitor's computer and then display it back to her when she returns.
The next sections cover creating and reading cookies.
Creating a Cookie
-
The first step in creating a cookie is to initialize the Cookie object:
<%
Cookie msgCookie = new Cookie("message", "JSP is cool!");
-
Next, specify when the cookie will expire, in seconds:
msgCookie.setMaxAge(3600);
-
Next, specify which of your JSP pages can access this cookie:
msgCookie.setPath("/jsp");
NOTE
For added security, specify your Web site domain (that is,
www.yourdomain.com
) with the setDomain() method: msgCookie.setDomain(
www.yourdomain.com
). This keeps unauthorized JSP pages from other sites from accessing the cookies you create.
-
Now send the cookie to the visitor's computer using the
response.addCookie()
method:
response.addCookie(msgCookie);
%>
-
Add whatever HTML to this page you think is appropriate, and save the file with a .jsp extension to a folder in your Web server's docroot.
The next time a visitor hits this .jsp page, a cookie containing a brief message will be saved to the visitor's system.
|
Although some people may not like the idea that a file is being written to their systems, cookies are stored as text files, not executable code. There have been no cases of viruses ever being spread using cookies.
Think about a Web world in which there were no cookies—you'd have to log in to your favorite sites each time, and those sites would have to resort to other methods to track what your interests and preferences are.
Also note that you can create any number of cookies to store visitor information, but most Web browsers limit a domain to storing 20 cookies on a visitor's computer at any one time.
|
Reading a Cookie
To read values stored on a computer as cookies, you can use the
request.getCookies()
method. Because you'll possibly be retrieving multiple values, store this information into an array and use a for loop to iterate over the array.
The for loop also allows the JSP page to test for the existence of cookies—if no cookies exist, or if the visitor doesn't allow cookies to be written to his or her system, the for loop will exit gracefully without
causing
an error.
-
First, set up the array that will hold the results of your cookie request:
<%
Cookie[] cookiesfromVisitor = request.getCookies();
-
Next, iterate over the elements of the array using a for loop and the length attribute:
for (int x = 0; x < cookiesfromVisitor.length; x++) {
-
Print out the
names
and values that are retrieved:
out.print(cookiesfromVisitor[x].getName() + " contains the value ");
out.print(cookiesfromVisitor[x].getValue() + "<br>");
}
%>
-
Save the file with a .jsp extension to your server's docroot.
JavaBeans
A JavaBean is a class file that stores Java code (for more on classes and objects, read the sidebar). Although you can do the same things with a JSP file as you would with a JavaBean,
putting
too much business logic inside your JSP pages is a bad idea.
For one thing, if you repeat code segments throughout your application, it becomes harder to debug and update your application. It's also harder to share your application with other developers that need to do the same or similar things.
JavaBeans solve both of these problems. JavaBean code is centralized, so any changes to a JavaBean ripples throughout your application. Other developers can also use your JavaBeans to extend their work—this is particularly useful whether developers create generic beans (which perform basic functions like data access) or highly specialized beans (which perform unique or
problematic
tasks).
|
Java is an object-oriented language, which means that any program written in Java is structured around objects—self-contained, reusable packets of procedures and data. Although object-oriented programming comes complete with a whole slew of specialized jargon, I'll provide a concrete metaphor to make it easier to understand.
Let's start with a familiar object in the real world—a car. A car is an object with certain properties. It has two or four doors, it has an engine of a certain size, a readout for current speed, a top speed, and a gas tank that holds so much gas.
A car is much more than a collection of properties, however. A car can also do things. It can
turn
left and right, accelerate, decelerate, and play music (if it has a radio). A sophisticated car may also have subcomponents that have their own unique mechanisms—I'm thinking here of chairs and mirrors that adjust to a driver's saved settings.
If a car were an object in the Java world, the properties (number of doors and so on) would be called fields. Fields in Java can store different types of information, such as text strings, integers, and references to other objects.
What an object can do would be called a method. A method can be generic or highly specialized, but each is
task-oriented
. Our car might have a method called accelerate() and another called turnLeft().
A car, however, doesn't pop into being all by itself, and
neither
does an object. An object needs a template, called a class file, to help define it. In fact, to a class file, an object is merely an instance of the class. A single class can create many different objects, just as a car factory can create many different
cars
.
The nice thing about objects is their extensibility. To put it into the terms of our ongoing metaphor, after you understand how to drive one kind of car (a sleek sports car) you can probably figure out how to drive another kind of car (a truck).
Why? Because all you have to know to get going are the properties and the methods. Think about it: Turning left with one car is the same as with another. Just turn the wheel counterclockwise. The car handles everything else, which means you don't have to know what's going on inside the guts of the machine.
Similarly, objects allow programmers to use methods (sometimes with passed-in arguments, or information the method needs to do its work) without having to understand all the details. The programmer uses an object's method, the method does its work behind the scenes, and out comes a result.
|
Creating a JavaBean
You can create a JavaBean in Dreamweaver MX or a text editor. JavaBeans are usually stored in the \classes directory of your Tomcat installation. The following instructions take you through each step of the process of creating your first JavaBean, which we'll call Name—we'll use it to set and get people's names.
-
In Dreamweaver MX or a text editor, declare your class and initiate the class's name variable by typing the following text in a new file:
public class Name {
private String name;
NOTE
Classes can be public (accessible by any class or object), protected (accessible only by its own class or subclasses
belonging
to the class), or private (accessible only by its own class). Most classes are public.
-
Now create some methods. The first method will be the object's constructor. Constructors always have the same name as the object, and they're usually used to instantiate variables and do other housekeeping when the Bean is built (or
constructed
). In the following example, the constructor sets the value of the string name to "Tom":
public Name() {
name = "Tom";
}
NOTE
Java is case sensitive, so that means that the name of the constructor method must match the name of the object. That means that the name(), NAME(), Name(), and NaME() methods are all
considered
different.
-
The second method, getName(), is known as the getter method. It enables you to get the value of the variable name from the object:
public String getName() {
return name;
}
-
The third method, setName(), is known as the setter method. It enables you to set a different value for the name variable:
public void setName(String newName){
name = newName;
}
NOTE
The void keyword indicates a method that does not return a value.
-
The fourth method will print out a series of
asterisks
:
public string asterisks (int num) {
String output = "";
for (int x = 0; x < num; x++) {
output = output + "*";
return output;
}
-
Make sure that you put in the curly brace that
closes
off the opening
brace
that started the class:
}
-
Finally, save your file as Name.java. In Java, you must name your source file the same as the name of the Bean. The same case-sensitive rules apply here as they did with the constructor.
Compiling a JavaBean
Now that you've created a Bean, you have to compile it. Compiling Java source code turns it into bytecode, which is executed by the Java interpreter. This bytecode is said to be
obfuscated
, because no one can
open
it up and see how your code works. This makes it more secure as well as faster.
-
Open a DOS prompt window and change directories to where you installed the Java Development Kit.
-
On the command line, type
javac
followed by the name of the .java file you want to compile. For example:
javac Name.java
-
If the Java compiler didn't run into any problems, the command prompt will reappear. When you list the directory contents, you'll notice a new file with the same name as your .java file, but with a .class extension:
Name.class
-
Copy the newly created .class file to the \classes directory under your Tomcat installation.
|
There are two types of errors you'll get when you compile Java source code: compiler errors and source code errors.
Compiler errors occur because your operating system can't find the Java compiler. Make sure that you're in the right directory and try again. If problems persist, you may have to reinstall Java.
Source code errors result from errors that the compiler finds in your source code. In this case, the compiler will display the type of error it found and on what line. In this case, open the .java file, make your changes, and try again.
|
Using a Java Bean from a JSP Page
Now that you've compiled a JavaBean, you're ready to use it from a JSP page. JSP provides the
<jsp:useBean>
for setting up a Bean. After you initialize the Bean using
<jsp:useBean>
, you can access that Bean's properties and methods.
To set up a JavaBean, follow these instructions:
-
In your JSP page, type the <jsp:useBean> tag. This tag has various properties that make it work: the class (which points to where the Bean resides), an id (to identify the instance within your JSP pages), and a scope (see the sidebar).
<jsp:useBean class="beans.Name" id="Name1" scope="session" />
-
To find out what value is set for this JavaBean's name property, you need to use the <jsp:getProperty> tag.
<jsp:getProperty name="Name1" property="name" />
NOTE
This tag must have a
counterpart
method inside the JavaBean. For the name property, the method must be named getName—in other words, the name of the method must be the same as the property, but the first letter is capitalized. The entire name is prefixed by get.
-
To change the value of this Bean's name property, you need to use the
<jsp:setProperty>
tag.
<jsp:setProperty name="Name1" property="name" value="Tony" />
NOTE
This tag must have a counterpart method inside the JavaBean. For the name property, the method must be named setName—in other words, the name of the method must be the same as the property, but the first letter is capitalized. The entire name is prefixed by set. Additionally, the setName method must be of type public void.
-
To see the change in the value assigned to the name variable, use the
<jsp:getProperty>
tag again:
<jsp:getProperty name="Name1" property="name" />
-
Now access the JavaBean's asterisks() method. Because this method returns a value, you can use an expression. In the following example, you're asking the asterisks() method to print out 10 asterisks (*) in a row:
<%= Name1.asterisks(10) %>
-
Save the file with a .jsp extension to a folder in your Web server's docroot.
-
Point your browser at the JSP file and view the results.
|
A JavaBean can exist for just one request or for as long as the application is online. The time it has to "live" is called scope. When you instantiate a JavaBean using the
<jsp:useBean>
tag, you don't have to set a scope—the default scope is set to page.
The scopes are defined next:
request
The JavaBean is available for only one request by a client.
page
The JavaBean is available only from the page that
instantiated
it (therefore, it can handle many requests).
session
The JavaBean is available to a single client for as long as that session continues.
application
The JavaBean is available to all
clients
for as long as the application is available.
|
|
Although you'll be using the
<jsp:useBean>
,
<jsp:getProperty>
, and
<jsp:setProperty>
actions frequently, other actions have nothing to do with beans and include:
<jsp:forward>
Enables you to forward visitors to another page.
<jsp:forward page="index2.jsp" />
<jsp:include
Enables you to include the contents of another file inside another file.
<jsp:include page="footer.html" flush="true" />
<jsp:param>
Enables you to add further name-value pairs to another action tag. For example, if you wanted to forward visitors to another page and then tell them, after they got to their destination, where they came from, you could add a sentFrom parameter to the
<jsp:forward>
tag:
<jsp:forward page="index2.jsp">
<jsp:param name="sentFrom" value="index.jsp" />
</jsp:forward>
NOTE
When you use a
<jsp:param>
tag, note the use of opening (
<jsp:...>
) and closing (
</jsp:...>
) action tags around it.
If you wanted to look up the sentFrom parameter on the destination page, use the
getParameter()
method of the request object, as you would with a form element:
<%= request.getParameter("sentFrom") %>
Be aware that when you use the
<jsp:forward>
tag, the server stops processing that page as soon as it hits that action tag.
|
Debugging JSP Code
You'll hardly ever create perfect code, even when you become an
experienced
JSP
coder
, so it's inevitable that you'll be presented with an error message when you run your code. Sometimes the error is simple (dividing by zero) and sometimes its more complex (using the wrong data type when attempting to cast an object).
Sometimes the error messages are useful, sometimes they're not. JSP provides error (or exception) handling routines that make it easier for you to understand the problem—and fix it.
Whenever an error occurs, an object is created that stores information about the error. This information is usually pasted onto the screen in place of the JSP page that's supposed to run:
Error:500
Location: /examples/math.jsp
Internal Servlet Error:
org.apache.myserver.myserverException: / by zero
at org.apache.myserver.runtime.JspServelt$JspServletWrapper...
The
easiest
way to keep this raw data dump from happening is to use a try…catch block. Use the try statement to encapsulate the block of code, and the catch block to handle any exceptions:
<html>
<title>Some Simple Math</title>
<body>
<h2>Some Simple Math</h2>
<%
int quantity = 0;
int cost = 100;
try {
int costperquantity = cost / quantity;
out.print("Cost per quantity is " + costperquantity);
}
catch(ArithmeticException e) {
out.print("Error occurred: did you divide by zero?<br>");
}
If you have a code block that may cause multiple errors, you can continue to add catch blocks that handle each exception type. These catch blocks can accurately pinpoint the problems
encountered
in any block of code and are a lot more useful than a giant screen full of error messages.
Another way to handle exception handling is to set a page directive that specifies an error-handling page and then do the error/exception handling there.
-
The first step is to add a page directive that sets the errorPage property. This directive must be at the top of a .jsp page:
<%@ page errorPage="error.jsp" %>
<html>
<title>Welcome</title>
<body>
Let's do some math:
<%
int bad = 100/0;
%>
</body>
</html>
-
Save the file as badmath.jsp to your Web server's docroot.
-
Next, create the error.jsp page. Make sure that the page starts off with a page directive that specifies the page as an error page:
<%@ page isErrorPage="true" %>
<html>
<title>An error has occurred</title>
<body>
<h1>An error has occurred</h1>
-
You can leave the file simple, with a message that says "An error has occurred," but you will more than likely need more detail than that. To get that detail, use the getMessage() method of the exception object:
Here's the error message:<br><br>
<% exception.getMessage() %>
</body>
</html>
-
Save the error.jsp page to the Web server docroot, then browse the badmath.jsp page. The browser should display the following error message:
Here's the error message:
/ by zero