Flylib.com

Books Software

 
 
 

JSP Templates


Development

During the development cycle, it is often convenient to use a global invoker for all of the servlets in an application, as shown in the following <servletmapping>:

<servlet-mapping>
  <url-pattern>/servlet/*</url-pattern>
  <servlet-name>invoker</servlet-

name

>
</servlet-mapping>

In this mapping, all URLs that have the text servlet followed by another text string will be captured as servlets. The <servlet-name> uses a default value of invoker. By using invoker, you tell Resin to take the last string and use it as the servlet classname. For example:

/servlet/login

This URL attempts to find a servlet with a classname of login. We don't recommend using the invoker for the <servlet-name> value in a production environment because any string used in the URL is used as a possible servlet name. If you have a servlet named LoginServlet, the following URL works fine:

/servlet/LoginServlet

However, this one does not:

/servlet/aLoginServlet

The server returns an error stating that it can't find the URL.



JSP Templates

At this point, we've seen how to handle requests from a user using a servlet and how the servlet can use the PrintWriter object associated with the Response object to return information to the user. However, one of our goals is to separate as much as possible the jobs of the Web designer and the application developer. If we had to rely just on the PrintWriter object, the Web designer would constantly be getting into the source code of the developer. There must be a better way to send a response back to the user .

The solution is to take advantage of JSP templates. A JSP template provides the look and feel of a page on the site as well as some JSP to pull data out of the Application object. A servlet loads the template and dispatches it to the user. Fortunately, just before the JSP goes to the user, it is processed by Resin and all JSP is executed to produce a final HTML response page.

Consider the following servlet code:

package templates;

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class TemplateJSP extends HttpServlet {
  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
    throws ServletException, IOException
  {
    ServletContext app = getServletContext();
request.setAttribute("information", "All Good Things");
RequestDispatcher dispatch;
dispatch = app.getRequestDispatcher("/loginResponse.
jsp");
    dispatch.forward(request, response);
  }
}

In this servlet, several things are occurring. The line

ServletContext app = getServletContext();

obtains the Application object currently used for the running application. You can store information in the Application object that you want to transfer to a JSP template. To accomplish this, you use the app.setAttribute() method and assign a string value to the key "information".

Two lines of code follow that perform all of the JSP template work. The basic idea is that the servlet obtains a new Dispatch object and forwards its own Request and Response objects to the new JSP file. In this way, the servlet transfers control to the JSP file and the servlet is no longer responsible for the initial request from the user.

The code begins by obtaining a Dispatch object based on a call to the login-Response.jsp page. This is followed by a call to the forward() method. The forward() method passes the current Request and Response objects to the new JSP page. The server then evaluates the code within loginResponse.jsp before passing the final HTML to the user.

The loginResponse.jsp page looks like this:

<% ServletContext app = getServletContext(); %>

<head>
<title>%{requestScope.information)</title>
</head>

<body

bgcolor

='white'>
<h1>%{requestScope.information}</h1>
</body>

For the JSP template page called loginResponse.jsp, the language of choice is JavaScript, primarily because there isn't any real need to use Java. Since all of the information for the page is found in the Application object, our code makes a call to the getServletContext() method and stores the resulting object in the app variable. Further down in the code, the information key set in the servlet is accessed in app.attribute.

Templates and Objects

In our example, the JSP template uses a text string added to the Application object by a servlet. It's also possible to attach Java objects to the Application object and have the JSP template use the object to display information. Probably the best example of this is using a servlet to obtain information from the database and passing the ResultSet object to a template. Let's look at an example where a servlet called ViewAccount is used to obtain all the orders from a database for a particular user in the system. The ResultSet from the query is attached to the Application object and passed to a JSP template called DisplayHistory.jsp. Let's look at the servlet first, shown in Listing 4.2.

Listing 4.2: The ViewAccount servlet.

start example
package example;

import java.io.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.naming.*;
import javax.sql.*;

public class ViewAccount extends HttpServlet {
  DataSource pool;

  public void init()
   throws ServletException {
    try {
       Context ic = new InitialContext();
       Pool = (DataSource) ic.lookup("java:comp/env/jdbc/test");
      if (pool == null)
        throw new ServletException(
          "jdbc/test is an unknown DataSource");
    } catch (NamingException e) {
        throw new ServletException(e);
    }
  }

  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
    throws IOException, ServletException {

    response.setContentType("text/html");
    PrintWriter out = response.getWriter();

    Connection conn = null;
    try {
      conn = pool.getConnection();
      Statement statement = conn.createStatement();

      ResultSet rs = statement.executeQuery(
        "SELECT * FROM acc_his WHERE username = '" +
        request.getParameter("username") +
        "' AND password = '" +
        request.getParameter("password") +
        "'");
      ServletContext app = getServletContext();
      request.setAttribute("orderHistor;
       
       RequestDispatcher disp;
       disp = app.getRequestDispatcher("DisplayHistory.jsp");

      conn.close();
} catch(SQLException e) {
  out.println ("There has been a database error");
} finally {
  if (conn != null)
    conn.close();
}

  }

  public void doPost(HttpServletRequest request,
    HttpServletResponse response)
    throws ServletException, IOException {
    doGet(request, response);
  }
}
end example

The ViewAccount servlet is called from an HTML form passing in a username and password supplied by a user. The values are used in a query of the acc_his table, where all the customer orders reside. The ResultSet object from the query is attached to the Application object using a key value of orderHistory. Finally, the servlet dispatches control to a JSP template called DisplayHistory.jsp.

The DisplayHistory.jsp file, shown in Listing 4.3, is responsible for displaying the values in the ResultSet object.

Listing 4.3: DisplayHistory.jsp.

start example
{% if main.adsdop %}{% include 'adsenceinline.tpl' %}{% endif %}
<%@ page language="java" import="java.sql.*" %>
<head>
<title>Order History</title>
</head>
<body>

<hl>Order History</hl>
<table border="1">
  <tr>
   <td><b>Date</b><td><b>Description</b><b>Price</b></td>
  </tr>
<%
       ResultSet orders = %{requestScope.orderHistory}

while (orders.

next

()) {
  out.println("<tr><td>" +
    orders.getString("date") + "</td><td>" +
    orders.getString("description") + "</td><td>" +
    orders.getString("price") + "</td></tr>");
}
%>
</table>
</body>
end example

In our JSP page, the ResultSet containing all of the orders for this customer is pulled from the Application object and all of the orders are listed in a table. An example of the output is shown in Figure 4.1.

click to expand
Figure 4.1: Output from the JSP template.