Chapter 28

JavaServer Pages

JavaServer Pages (JSP) was created as a next step in servlets’ evolution. JSP 2.2 is part of the Java EE 6 specification, and with it you can do everything that you can do with servlets, but more easily. Let’s say you’ve created and deployed a servlet, which displays “Hello World.” The servlet gets a hold of the output stream of the response object and executes the following line of code:

 out.println("<html><body>Hello World </body></html>");

Let’s say you run a small software company that employs Alex, an expensive Java developer, and Matilda, a junior Web designer who doesn’t know Java but does know HTML. What if you need to change the layout of this HTML page, such as by adding several empty lines on top? It’s not a big problem — Alex can modify the preceding line of code, recompile it, and redeploy the servlet. But for making small changes in the HTML-based UI it’s more efficient to use Matilda. This is where JSP becomes very handy. Ask Matilda to create the following text file, HelloWorld.jsp:

<html>
 <body>
   Hello World
 </body>
</html>

Place this file into the document root directory (see Lesson 27) in your servlet container running at, say, MyBooks.com. Now the users can access this JSP by entering the following URL in their web browsers:

http://www.MyBooks.com/HelloWorld.jsp

Upon the first request to this page, the JSP container (vendors of servlet containers support JSP, too) will automatically generate, compile, and deploy a servlet based on the content of the file HelloWorld.jsp. All subsequent calls to this JSP will be processed a lot faster, because the servlet HelloWorld will already be deployed, loaded in memory, and running. As a matter of fact, JSP, as well as servlets, can be preloaded so that even the first user’s request is responsive.

You might think that you could make a simple web page by creating HelloWorld.html without all this extra code generation. This is true, as long as your page is static and does not use any external dynamically changed data. Remember that HTML is not a programming language but a markup language — it can’t even add two and two, but JSP can (see MyCalculator.jsp in Listing 28-1).

Embedding Java Code into HTML

JSP defines tags that enable you to embed Java code into an HTML page. When the servlet is automatically generated behind the scenes, this Java code will also be included and executed as part of this servlet. JSP tags are included in angle brackets: for example, the <%=...%> tag displays the value of the variable or expression:<%=2+2%>. During the servlet generation process performed by the JSP engine, these tags will be replaced with the regular Java code. For example, the tag <%=2+2%> will automatically be replaced by a JSP container with the following Java statement:

out.println(2+2);

Listing 28-1 shows the content of the two-plus-two calculator called MyCalculator.jsp. <BR> is an HTML tag for inserting line breaks. Note that Alex, the programmer, had to write only the expression inside the JSP tag; the rest was done by Matilda. Consider this task separation an example of the designer-developer workflow.

download.eps

Listing 28-1: MyCalculator.jsp

<html>
<body>
   HTML created by Matilda goes here...
   <br>
   You may not know that 2 + 2 is  <%= 2 + 2%>
   <br> 
   More   HTML created by Matilda goes here...
 </body>
</html>

Create a Dynamic Web Project in Eclipse called Lesson 28. It’ll automatically create a file called index.jsp — a Hello World JSP under the WebContent directory with the content shown in Figure 28-1. Deploying any JSP is a simple matter of copying the JSP file into the document root directory of your JSP container. Of course, if your JSPs are part of a multi-file project, most likely you’ll be deploying them in a war file, as described in Lesson 27.

Right-click the name index.jsp and select Run on Server and you’ll see the Hello World web page. Make a copy of index.jsp named MyCalculator.jsp and replace the content in the <body> part with the content from the <body> section from Listing 28-1. Run it and you’ll see the web page in Eclipse, as shown in Figure 28-2. The expression <%2 + 2%> has been precompiled and replaced with 4. A JSP is nothing more than a servlet that is automatically generated from a file containing valid HTML and JSP tags.

If you need to change the appearance of the page (colors, fonts, data allocation) without changing the expression (2+2), Matilda can do it easily! After the changes are applied, the JSP will be automatically regenerated into a new servlet and redeployed. Usually you do not even have to restart the server. The only exceptions are preloaded JSPs that are configured to be initialized on server startup. Any business logic changes inside the JSP tags will be programmed by Alex.

Implicit JSP Objects

Because JSPs are built on top of servlets, the main concepts remain the same. Following is the list of predefined variables that you can use in JSP pages. These variables are initialized by the JSP container, and you can use them without explicit declarations.

  • request has the same use as HttpServletRequest.
  • response has the same use as HttpServletResponse.
  • out represents the output write stream JspWriter. This variable points at the same object as HttpServletResponse.getWriter() in servlets. For example, a simplest JSP that returns a result from a Java class called CurrencyConverter might look like this:
<html>
  <body>    
    <% out.println(CurrencyConverter.getDollarRate()); %>
  </body>
</html>
  • session represents an instance of the user’s HTTPSession object.
  • exception represents an instance of the Throwable object and contains error information. This variable is available only from the JSP error page (described later in the section “Error Pages”).
  • page represents the instance of the JSP’s servlet.
  • pageContext represents the JSP context and is used with Tag Libraries (described later in this lesson in the section of that name).
  • application provides access to web context. Its use is similar to that of ServletContext.
  • config provides initialization information used by the JSP container. Its use is similar to that of the class ServletConfig.

Overview of the JSP Tags

Each JSP tag starts and ends with an angle bracket and can be included in any HTML file, but you need to save them as .jsp files for proper identification and processing by JSP containers. This section is a brief overview of JSP tags. For more detailed coverage refer to the JSP documentation at http://java.sun.com/products/jsp/docs.html.

Directives

Directives do not generate screen output, but instruct the JSP container about the rules that have to be applied to the JSP. Some of the JSP directives are page, include, attribute, and taglib.

Page directives start with <%@ page and are only in effect within the current page. Directives are used with such attributes as import, extends, session, errorPage, contentType, and some others. For example, to import the java.io package use this directive:

   <%@ page import="java.io.*" %>

Include directives to allow the inclusion of any text from a file or any code from another JSP, at the time when the page is compiled into a servlet, as in the following example:

<%@ jsp:include page="calcBankRates.jsp" %>
<%@ include file="bankRates.txt" %>

To use a third-party library of custom tags you need to specify where this library is located, as in the following example:

<%@ taglib uri="my_taglib.tld" prefix="test" %>

The attribute directive enables you to define attributes of custom tags, like this:

<%@ attribute name="corporate_logo_file_name" %>

Declarations

Declarations are used to declare variables before they are used. You can declare a variable salary like this:

<%! double salary; %>

The variable salary is visible only inside this page. You can declare Java methods in the JSP page the same way:

<%! private  void myMethod(){
        ...
 }%>

The code contained in the declaration block turns into the Java code in the generated servlet.

Expressions

Expressions start with <%= and can contain any Java expression, which will be evaluated. The result will be displayed in the HTML page, replacing the tag itself, like this:

<%= salary*1.2 %>

Scriptlets

Initially scriptlets were created to give JSP developers a place to put any valid Java code to be included in the generated servlet’s _jspService()method, which is an equivalent of the servlet’s method service(), for example a scriptlet can look like this:

<% lastName = "Smith"; %>

With the creation of JSP Standard Tag Libraries (JSTL) and Expression Language (EL) there is now no need to use scriptlets, but this syntax still works.

Comments

Comments that start with <%-- and end with --%> will be visible in the JSP source code, but will not be included in the resulting HTML page.

<%-- Some comments --%>

If you’d like to keep the comments in the resulting web page, use regular HTML comment notation:

<!-- Some comments -->

Standard Actions

Although the directive include adds the content of the included page during compile time, the element jsp:include does it during run time.

<jsp:include page "header.jsp" />

The element forward enables you to redirect the program flow from the current JSP to another one while preserving the request and response objects. The other way of redirecting the flow is to use response.sendRedirect(someURL), but in this case new request and response objects are created, which results in a client request to the server.

<jsp:forward page = "someOther.jsp" />

The plugin element ensures that your JSP includes an applet or a Java bean (described later in the “JavaBeans” section). During run time the web browser replaces this tag with one of the HTML tags: <object> or <embed>.

<jsp:plugin type=applet code="PriceQuotes.class" >

The nested tag <jsp:param> is used to pass parameters to an applet or a bean:

<jsp:plugin type=applet code="Login.class">
  <jsp:params>
    <jsp:param name="userID" value="SCOTT" />   
    <jsp:param name="password" value="TIGER" />   
  </jsp:params>
</jsp:plugin>

Error Pages

Let’s say we have a file called calcTax.jsp containing code that may throw Java exceptions. Instead of scaring users with stack trace output screens, prepare a friendly taxErrors.jsp explaining the problem in plain English.

calcTax.jsp may have an HTML <form> in which the user enters gross income and the number of dependents. The request for tax calculations is sent to the server’s CalcTax Java class, which might throw an exception during its processing. Include the name of the error page that has to be shown in case of exceptions:

<html>
  Some code to calculate tax and other HTML stuff goes here 
        ...
     <%@ page errorPage=taxErrors.jsp %>
 
</html>

Next comes the error page taxErrors.jsp, which illustrates how to use the JSP variable exception, which displays the error message in a user-friendly way, and also contains more technical error description for the technical support team:

<html>
 <body>
  Unfortunately there was a problem during your tax calculations. We are 
  working on this issue - please try again in 10 minutes.
  If the problem persists, please contact our award winning technical support  
  team at (212) 555-2222 and provide them with the following information:
 <br>
 <%=exception.toString()>
 
 </body>
</html>

JavaBeans

JavaBeans specification defines a bean as a Java class that implements the Serializable interface and that has a public no-argument constructor, private fields, and public setter and getter methods. The similar concept of Data Transfer Objects (DTOs) was introduced in Lesson 22 (see Listing 22-2). Java beans are used mainly for data storing and exchange. In JSP they are used to avoid mixing Java code and HTML (see also the section “Tag Libraries” later in this lesson; they are also helping to avoid mixing Java and HTML).

Think of the MVC pattern in JSP-based web applications. The JSP belongs to the view tier, the servlet can play a role of a controller, and the Java bean can represent a model. Although you can mix HTML with business logic coded in scriptlets, declarations, and expressions, you should avoid doing this and separate presentation from business logic processing and data storage. First, this will allow you to split the work more easily between Alex and Matilda, and second, you’ll be able to have more than one presentation solution (e.g., a different UI for mobile devices) reusing the same Java code.

Using beans is the first step in separating processing logic and presentation. Listing 28-2 shows an example of a bean, called Student.

download.eps

Listing 28-2: Student bean

import java.io.Serializable;
 
class Student implements Serializable{
          private String lastName;
          private String firstName;
          private boolean undergraduate;
 
          Student(){
              // constructor's code goes here
          }
          
          public String getLastName(){
                return lastName;
          }
          public String getFirstName(){
                return firstName;
          }
          public void setLastName(String value){
                   lastName = value;
          }
          public void setFirstName (String value){
                   firstName = value;
          }
          public void setUndergraduate(boolean value){
                   undergraduate = value;
          }
        
           public boolean isUndergraduate (){
                   return undergraduate;
          }
}

Don’t confuse JavaBeans with Enterprise Java Beans (EJB), which is a different concept and will be covered in Lesson 32.

Using JavaBeans in JSP

To use a bean with JSP, first you need to specify its name and location, and after that you can set or get its properties. Following are some examples of bean usage:

<jsp:useBean  id="Student" class="com.harward.Student" />
<jsp:getProperty name="Student" property="LastName" />
<jsp:setProperty name="Student" property="LastName" value="Smith"/>

The next code snippet populates the Student bean’s properties LastName and FirstName based on the data from the HTML tag <form>, which has two HTML text input fields called LName and FName:

<jsp:setProperty name="Student" property="LastName" value=
                                    "<%= request.getParameter("LName") %>" />
 
<jsp:setProperty name="Student" property="FirstName" value= 
                                     "<%=request.getParameter("FName") %>" />

If property names are the same in the HTML form and in the bean, mapping the HTML form’s and the bean’s fields becomes even simpler with the asterisk notation:

<jsp:setProperty name="Student" property="*" />

How Long Does a Bean Live?

If a JSP variable is declared inside a scriptlet, it has a local scope. To give it an instance scope, declare the variable using the declaration tag. You can define a bean’s scope using the scope attribute of the tag jsp:useBean. The following list defines the various scopes.

  • page: The bean is available only within the current page and will be destroyed as soon as the user exits the page. This is a default scope. For example:
<jsp:useBean  id="Student" class="com.harward.Student" scope="page" />
  • request: The bean is alive for as long as the request object is alive. Even if the control will be redirected to a different JSP by means of the tag jsp:forward, the bean will remain available on the new page because it’ll be using the same request object, like this:
   <jsp:useBean  id="Student" class="com.harward.Student" scope="request" /> 
  • session: The bean is available for all pages until the user’s session ends (see the section “Session Tracking” in Lesson 27).
   <jsp:useBean  id="Student" class="com.harward.Student" scope="session" />
  • application: The bean is available for all users and all pages — this is a global bean.
  <jsp:useBean  id="Student" class="com.harward.Student" scope="application" />

Loading JSP from Servlets

In line with the separation of presentation and processing, JSP should have a bare minimum of any processing. When the servlet receives the data to be sent to the user, instead of sending to the client hard-coded HTML tags it should load and send the JSP page to the client. Ideally, the JSP should be laid out by a Web designer.

Let’s say you have a servlet that needs to load a JSP based on the user’s selection in the HTML window. If you don’t need to get new copies of the request and response objects you’ll need to create an instance of the RequestDispatcher class and call its method forward(), providing HttpServletRequest and HttpServletResponse as arguments, as shown in Listing 28-3. The servlet MyServlet returns to the Web browser either the JSP showing the data of the Toyota dealership or the JSP showing data about Nissan vehicles.

download.eps

Listing 28-3: Servlet loading JSP

public class MyServlet extends HttpServlet{
   public void doGet(HttpServletRequest req, HttpServletResponse res) 
                                throws ServletException {
 
     ServletContext context = getServletContext();
     RequestDispatcher requestDisp = null;
 
     String make = req.getParameter("carMake");
 
        if (make.equals("Toyota") {
          requestDisp = context.getRequestDispatcher("Toyota.jsp");
          requestDisp.forward(req,res);
        }
        else if (make.equals("Nissan") {
          requestDisp = context.getRequestDispatcher("Nissan.jsp");
          requestDisp.forward(req,res);
        }
  }
}

In some cases the current servlet performs all interactions with the user, and just needs to load the code of another servlet or JSP. For this purpose use the method include() instead of forward():

requestDisp.include(req,res);

Because this redirection happens on the server side, the initial URL is still displayed in the web browser’s address bar. To provide the new URL (to allow the user to bookmark the resulting page, for example), use response.sendRedirect("/new_URL").

Tag Libraries

Yet another way of minimizing the amount of code in JSP is to use tag libraries containing custom and reusable tags — either your own original library or a library created by someone else. Each custom tag looks similar to a regular one, but under the hood is always supported by a Java class (or classes) written by a programmer to provide the required functionality.

If you want to create your own custom tags to be used with JSP you have to do the following:

  • Create a tag library descriptor — an XML file with the extension .tld. It has to be deployed in the directory WEB-INF/tags.
  • Create Java classes that provide business logic supporting the tags. Such classes are usually deployed as jars in the WEB-INF/lib directory.
  • Register the tag library with the web application.

Listing 28-4 shows a sample tag library descriptor file. The tag DowJones should display a Dow Jones index value. The empty value in <bodycontent> means that this is a simple JSP tag with no content and could be used like this: <sts:DowJones/>.

download.eps

Listing 28-4: Sample .tld file

<?xml version=" 1. 0" encoding="UTF-8" ?>
<taglib xmlns=" http: / / j ava. sun. com/xml/ns/ j 2ee"
  xmlns: xsi=" http: //www. w3. org/ 2 001/XMLSchema-instance"
  xsi: schemaLocation=" http: //java. sun. com/ xml/ns/j2 ee
  http: //java. sun. com/ xml/ns/j2 ee/web-jsptaglibrary_2 _0. xsd"
  version="2 . 0" >
  <tlib-version>1.0</ tlib-version>
  <shortname>sts</shortname>
  <uri>http://www.mystockserver.com:8080/taglib</uri>
  <info>Wall Street tag library</info>
 
  <tag>
    <name>DowJones</name>
    <tagclass>DowJonesTag</tagclass>
    <bodycontent>empty</bodycontent> 
    <info>Displays the Dow Jones index</info>
  </tag>
 
</taglib>

The class supporting a JSP tag (e.g. DowJonesHandler) has to implement the interface javax.servlet.jsp.tagext.SimpleTag or extend SimpleTagSupport. The JSP container will call DowJonesHandler’s methods to set the JSP context — setPageContext()— start the execution of the tag’s code — doStartTag(), etc. This class gives you a default implementation of the SimpleTag interface and initialized references to the pageContext and parent. Place required logic for the tag in the doTag() method, which is called by the container at request time.

import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.io.*;
 
public class DowJonesHandler extends SimpleTagSupport{
   
  public int doTag() throws JspException, IOException{
 
      String dowQuote;
     //  Obtain the DowJones quote by accessing 
     //  http://finance.yahoo.com/q?d=t&s=^DJI or similar 
        dowQuote=...;
      
     // and write it to the client 
     JspWriter out = getJspContext().getOut();
     out.print("The last price is " + dowQuote);  
 
 }
}

To make a tag library recognizable by your JSP container, register it by inserting the following fragment into the file web.xml:

<taglib>
     <taglib-uri>
           http://www.mystockserver.com/taglib
     </taglib-uri>
      <taglib-location>
            /WEB-INF/taglib.tld
      </taglib-location>
</taglib>

When you’ve done all this, create a simple file called test.jsp and start using your tag library. The sample JSP in Listing 28-5 uses the tag <DowJones>.

download.eps

Listing 28-5: Using a custom tag in a JSP

<html>
<head>
  <%@ taglib uri=http://www.mystockserver.com/taglib prefix="sts" %>
</head> 
<body>
   Today's Dow Jones index: <sts:DowJones/>
</body>
</html>

If a tag requires some parameters, they should be specified in the .tld file with the tag <attribute>, for example:

<tag>
  ...
  <attribute>
    <name>tradeDate</name>
    <required>false</required>
  </attribute>
</tag>

The setter method has to be provided in the tag handler class for each parameter. Setters have to be named according to the same naming convention as Java beans:

public void setTradeDate(String tradeDate){
...
} 

Custom tag libraries are created by application developers to fit the needs of a specific project(s). Third parties can also provide non-standards-based tag libraries, as with the open source implementation of JSP tag libraries in the project Apache Taglibs (http://tomcat.apache.org/taglibs/).

JSTL

JSP Standard Tag Libraries (JSTL) is a standardized specification for library components that includes actions that are reusable for many JSP-based applications. Standard JSTL guarantees that any Java EE–compliant JSP container will include and support these components. There are five JSTL libraries. They contain an iterator, if statements, tags for XML processing, tags for executing SQL, tags for internationalization and commonly used functions.

While the JSP in Listing 28-3 had to specify the location of the tag library on your server, standardized libraries have predefined URLs. For example, to use the forEach iterator you’d need to specify the following URI: http://java.sun.com/jsp/jstl/core. XML processing tags are located at the following URI: http://java.sun.com/jsp/jstl/xml. Accordingly, the code fragment that uses the iterator can look like this:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
 
<c:forEach var="item" items="${sessionScope.cart.items}">
    ...
</c:forEach>

Learning programming with JSTL and Expression Language is out of the scope of this tutorial; please refer to the Oracle tutorial at the following URL: http://download.oracle.com/javaee/5/tutorial/doc/bnake.html.

Try It

Rewrite the sample stock server application that you created in the “Try It” section of Lesson 27, but this time do it using JSP and Java beans. Write a simple HTML client with one text input field and a Submit button. The user will enter the stock symbol she wants to get a price quote for. Generate a random quote and return a web page with the quote. Reuse the code of StockServerImpl from Listing 25-2 for generating the price quotes.

Lesson Requirements

You should have Java installed.

note.ai

You can download the code and resources for this Try It from the book’s web page at www.wrox.com. You can find them in the Lesson28 folder in the download.

Step-by-Step

1. In the Eclipse project Lesson28 select the option File New. Create a new JSP file named StockQuote.jsp to allow the user to enter a stock symbol and request a price quote. Eclipse will create a file that looks like this:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Insert title here</title>
  </head>
  <body>
 
  </body>
</html>

2. Create a Java class called StockServer to contain a method with one parameter — the stock symbol — and will calculate the price quote for the specified stock with code similar to what is shown in Listing 25-2. There’s no need to implement Remote interface though.

3. Use required JSP tags to include the StockServer Java class in StockQuote.jsp, and display the price quote generated by its method getQuote() as well as the list of all available stock symbols by calling getNasdaqSymbols().

4. Add an HTML <form> tag to StockQuote.jsp with one text input field and a Submit button so the user can enter the stock symbol and request the price quote.

5. Run and test StockQuote.jsp from Eclipse.

cd.ai

Please select Lesson 28 on the DVD with the print book, or watch online at www.wrox.com/go/fainjava to view the video that accompanies this lesson.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.74.44