3.4. Structuring Autogenerated Servlets: The JSP page Directive

A JSP directive affects the overall structure of the servlet that results from the JSP page. The following templates show the two possible forms for directives. Single quotes can be substituted for the double quotes around the attribute values, but the quotation marks cannot be omitted altogether. To obtain quote marks within an attribute value, precede them with a backslash, using for and " for ".

<%@ directive attribute="value" %> 

<%@ directive attribute1="value1" 
              attribute2="value2" 
              ... 
              attributeN="valueN" %> 

In JSP, there are three types of directives: page, include, and taglib. The page directive lets you control the structure of the servlet by importing classes, customizing the servlet superclass, setting the content type, and the like. A page directive can be placed anywhere within the document; its use is the topic of this section. The second directive, include, lets you insert a file into the servlet class at the time the JSP file is translated into a servlet. An include directive should be placed in the document at the point at which you want the file to be inserted; it is discussed in Section 3.5. JSP 1.1 introduced a third directive, taglib, which is used to define custom markup tags; it is discussed in Section 3.7.

The page directive lets you define one or more of the following case-sensitive attributes: import, contentType, isThreadSafe, session, buffer, autoflush, extends, info, errorPage, isErrorPage, language, and pageEncoding. These attributes are explained in the following subsections.

The import Attribute

The import attribute of the page directive lets you specify the packages that should be imported by the servlet into which the JSP page gets translated. As illustrated in Figure 3-8, using separate utility classes makes your dynamic code easier to maintain, debug, and reuse, and your utility classes are sure to use packages.

Figure 3-8. Strategies for invoking dynamic code from JSP.


In fact, all of your utility classes should be placed in packages. For one thing, packages are a good strategy on any large project because they help protect against name conflicts. With JSP, however, packages are absolutely required. That’s because, in the absence of packages, classes you reference are assumed to be in the same package as the current class. For example, suppose that a JSP page contains the following scriptlet.

<% Test t = new Test(); %> 

Now, if Test is in an imported package, there is no ambiguity. But, if Test is not in a package, or the package to which Test belongs is not explicitly imported, then the system will assume that Test is in the same package as the autogenerated servlet. The problem is that the autogenerated servlet’s package is not known! It is quite common for servers to create servlets whose package is determined by the directory in which the JSP page is placed. Other servers use different approaches. So, you simply cannot rely on packageless classes to work properly. The same argument applies to beans (Section 3.6), since beans are just classes that follow some simple naming and structure conventions.

Core Approach

Always put your utility classes and beans in packages.


By default, the servlet imports java.lang.*, javax.servlet.*, javax.servlet.jsp.*, javax.servlet.http.*, and possibly some number of server-specific entries. Never write JSP code that relies on any server-specific classes being imported automatically.

Use of the import attribute takes one of the following two forms.

<%@ page import="package.class" %> 
<%@ page import="package.class1,...,package.classN" %> 

For example, the following directive signifies that all classes in the java.util package should be available to use without explicit package identifiers.

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

The import attribute is the only page attribute that is allowed to appear multiple times within the same document. Although page directives can appear anywhere within the document, it is traditional to place import statements either near the top of the document or just before the first place that the referenced package is used.

Note that, although the JSP pages go in the normal HTML directories of the server, the classes you write that are used by JSP pages must be placed in the special servlet directories (e.g.,.../WEB-INF/classes; see Sections 1.7 and 1.9).

For example, Listing 3.10 presents a page that uses three classes not in the standard JSP import list: java.util.Date, moreservlets.ServletUtilities (see Listing 2.17), and moreservlets.LongLivedCookie (see Listing 2.18). To simplify references to these classes, the JSP page uses

<%@ page import="java.util.*,moreservlets.*" %> 

Figures 3-9 and 3-10 show some typical results.

Figure 3-9. ImportAttribute.jsp when first accessed.


Figure 3-10. ImportAttribute.jsp when accessed in a subsequent request.


Listing 3.10. ImportAttribute.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> 
<HTML> 
<HEAD> 
<TITLE>The import Attribute</TITLE> 
<LINK REL=STYLESHEET 
      HREF="JSP-Styles.css" 
      TYPE="text/css"> 
</HEAD> 
<BODY> 
<H2>The import Attribute</H2> 
<%-- JSP page directive --%> 
<%@ page import="java.util.*,moreservlets.*" %> 
<%-- JSP Declaration --%> 
<%! 
private String randomID() {
  int num = (int)(Math.random()*10000000.0); 
  return("id" + num); 
} 
private final String NO_VALUE = "<I>No Value</I>"; 
%> 
<%-- JSP Scriptlet --%> 
<% 
Cookie[] cookies = request.getCookies(); 
String oldID = 
  ServletUtilities.getCookieValue(cookies, "userID", NO_VALUE); 
if (oldID.equals(NO_VALUE)) {
  String newID = randomID(); 
  Cookie cookie = new LongLivedCookie("userID", newID); 
  response.addCookie(cookie); 
} 
%> 
<%-- JSP Expressions --%> 
This page was accessed on <%= new Date() %> with a userID 
cookie of <%= oldID %>. 
</BODY> 
</HTML> 

The contentType Attribute

The contentType attribute sets the Content-Type response header, indicating the MIME type of the document being sent to the client. For more information on MIME types, see Table 2.1 (Common MIME Types) in Section 2.8 (The Server Response: HTTP Response Headers).

Use of the contentType attribute takes one of the following two forms.

<%@ page contentType="MIME-Type" %> 
<%@ page contentType="MIME-Type; charset=Character-Set" %> 

For example, the directive

<%@ page contentType="application/vnd.ms-excel" %> 

has the same effect as the scriptlet

<% response.setContentType("application/vnd.ms-excel"); %> 

The main difference between the two forms is that response.setContentType can be invoked conditionally whereas the page directive cannot be. Setting the content type conditionally is occasionally useful when the same content can be displayed in different forms—for an example, see the Section “Generating Excel Spreadsheets” starting on page 254 of Core Servlets and JavaServer Pages (available in PDF at http://www.moreservlets.com).

Unlike regular servlets, where the default MIME type is text/plain, the default for JSP pages is text/html (with a default character set of ISO-8859-1). Thus, JSP pages that output HTML in a Latin character set need not use contentType at all. But, pages in JSP 1.1 and earlier that output other character sets need to use contentType even when they generate HTML. For example, Japanese JSP pages might use the following.

<%@ page contentType="text/html; charset=Shift_JIS" %> 

In JSP 1.2, however, the pageEncoding attribute (see details later in this section) can be used to directly specify the character set.

Listing 3.11 shows a JSP page that generates tab-separated Excel output. Note that the page directive and comment are at the bottom so that the carriage returns at the ends of the lines don’t show up in the Excel document (remember: JSP does not ignore white space—JSP usually generates HTML where most white space is ignored by the browser). Figure 3-11 shows the result in Internet Explorer on a system that has Microsoft Office installed.

Figure 3-11. Excel document (Excel.jsp) in Internet Explorer.


Listing 3.11. Excel.jsp
First   Last    Email Address 
Marty   Hall    [email protected] 
Larry   Brown   [email protected] 
Steve   Balmer  [email protected] 
Scott   McNealy [email protected] 
<%@ page contentType="application/vnd.ms-excel" %> 
<%-- There are tabs, not spaces, between columns. --%> 

The isThreadSafe Attribute

The isThreadSafe attribute controls whether the servlet that results from the JSP page will implement the SingleThreadModel interface (Section 2.3). Use of the isThreadSafe attribute takes one of the following two forms.

<%@ page isThreadSafe="true" %> <%-- Default --%> 
<%@ page isThreadSafe="false" %> 

With normal servlets, simultaneous user requests result in multiple threads concurrently accessing the service method of the same servlet instance. This behavior assumes that the servlet is thread safe; that is, that the servlet synchronizes access to data in its fields so that inconsistent values will not result from an unexpected ordering of thread execution. In some cases (such as page access counts), you may not care if two visitors occasionally get the same value, but in other cases (such as user IDs), identical values can spell disaster. For example, the following snippet is not thread safe since a thread could be preempted after reading idNum but before updating it, yielding two users with the same user ID.

<%! private static int idNum = 0; %> 
<% 
String userID = "userID" + idNum; 
out.println("Your ID is " + userID + "."); 
idNum = idNum + 1; 
%> 

The code should have used a synchronized block. This construct is written

synchronized(someObject) { ... } 

and means that once a thread enters the block of code, no other thread can enter the same block (or any other block marked with the same object reference) until the first thread exits. So, the previous snippet should have been written in the following manner.

<%! private static int idNum = 0; %> 
<% 
synchronized(this) { 
  String userID = "userID" + idNum; 
  out.println("Your ID is " + userID + "."); 
  idNum = idNum + 1; 
} 
%> 

That’s the normal servlet behavior: multiple simultaneous requests are dispatched to multiple threads that concurrently access the same servlet instance. However, if a servlet implements the SingleThreadModel interface, the system guarantees that there will not be simultaneous access to the same servlet instance. The system can satisfy this guarantee either by queuing all requests and passing them to the same servlet instance or by creating a pool of instances, each of which handles a single request at a time. The possibility of a pool of instances explains the need for the static qualifier in the idNum field declaration in the previous examples.

You use <%@ page isThreadSafe="false" %> to indicate that your code is not thread safe and thus that the resulting servlet should implement SingleThreadModel. The default value is true, which means that the system assumes you made your code thread safe and it can consequently use the higher-performance approach of multiple simultaneous threads accessing a single servlet instance.

Explicitly synchronizing your code as in the previous snippet is preferred whenever possible. In particular, explicit synchronization yields higher performance pages that are accessed frequently. However, using isThreadSafe="false" is useful when the problematic code is hard to find (perhaps it is in a class for which you have no source code) and for quick testing to see if a problem stems from race conditions at all.

Core Note

With frequently accessed pages, you get better performance by using explicit synchronization than by using the isThreadSafe attribute.


The session Attribute

The session attribute controls whether the page participates in HTTP sessions. Use of this attribute takes one of the following two forms.

<%@ page session="true" %> <%-- Default --%> 
<%@ page session="false" %> 

A value of true (the default) indicates that the predefined variable session (of type HttpSession) should be bound to the existing session if one exists; otherwise, a new session should be created and bound to session. A value of false means that no sessions will be used automatically and attempts to access the variable session will result in errors at the time the JSP page is translated into a servlet. Turning off session tracking may save significant amounts of server memory on high-traffic sites. Just remember that sessions are user specific, not page specific. Thus, it doesn’t do any good to turn off session tracking for one page unless you also turn it off for related pages that are likely to be visited in the same client session.

The buffer Attribute

The buffer attribute specifies the size of the buffer used by the out variable, which is of type JspWriter. Use of this attribute takes one of two forms.

<%@ page buffer="sizekb" %> 
<%@ page buffer="none" %> 

Servers can use a larger buffer than you specify, but not a smaller one. For example, <%@ page buffer="32kb" %> means the document content should be buffered and not sent to the client until at least 32 kilobytes have been accumulated, the page is completed, or the output is explicitly flushed (e.g., with response.flushBuffer). The default buffer size is server specific, but must be at least 8 kilobytes. Be cautious about turning off buffering; doing so requires JSP elements that set headers or status codes to appear at the top of the file, before any HTML content.

The autoflush Attribute

The autoflush attribute controls whether the output buffer should be automatically flushed when it is full or whether an exception should be raised when the buffer overflows. Use of this attribute takes one of the following two forms.

<%@ page autoflush="true" %> <%-- Default --%> 
<%@ page autoflush="false" %> 

A value of false is illegal when buffer="none" is also used.

The extends Attribute

The extends attribute designates the superclass of the servlet that will be generated for the JSP page and takes the following form.

<%@ page extends="package.class" %> 

This attribute is normally reserved for developers or vendors that implement fundamental changes to the way that pages operate (e.g., to add in personalization features). Ordinary mortals should steer clear of this attribute.

The info Attribute

The info attribute defines a string that can be retrieved from the servlet by means of the getServletInfo method. Use of info takes the following form.

<%@ page info="Some Message" %> 

The errorPage Attribute

The errorPage attribute specifies a JSP page that should process any exceptions (i.e., something of type Throwable) thrown but not caught in the current page. The designated error page must use isErrorPage="true" (see next entry) to indicate that it permits use as an error page. The errorPage attribute is used as follows.

<%@ page errorPage="Relative URL" %> 

The exception thrown will be automatically available to the designated error page by means of the exception variable. For an example, see Section 11.10 of Core Servlets and JavaServer Pages (available in PDF at http://www.moreservlets.com).

Note that the errorPage attribute is used to designate page-specific error pages. To designate error pages that apply to an entire Web application or to various categories of errors within an application, use the error-page element in web.xml. For details, see Section 5.8 (Designating Pages to Handle Errors).

The isErrorPage Attribute

The isErrorPage attribute indicates whether the current page can act as the error page for another JSP page. Use of isErrorPage takes one of the following two forms:

<%@ page isErrorPage="true" %> 
<%@ page isErrorPage="false" %> <%-- Default --%> 

The language Attribute

At some point, the language attribute is intended to specify the underlying programming language being used, as below.

<%@ page language="cobol" %> 

For now, don’t bother with this attribute since java is both the default and the only legal choice.

The pageEncoding Attribute

The pageEncoding attribute, available only in JSP 1.2, defines the character encoding for the page. The default value is ISO-8859-1 unless the contentType attribute of the page directive is specified, in which case the charset entry of contentType is the default.

XML Syntax for Directives

All JSP 1.2 servers (containers) and some JSP 1.1 servers permit you to use an alternative XML-compatible syntax for directives as long as you don’t mix the XML version and the normal version in the same page. These constructs take the following form:

<jsp:directive.directiveType attribute="value" /> 

For example, the XML equivalent of

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

is

<jsp:directive.page import="java.util.*" /> 

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

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