18.4 Directives

Java Servlet Programming, 2nd Edition > 18. JavaServer Pages > 18.4 Directives

 
< BACKCONTINUE >

18.4 Directives

A JSP directive allows a JSP page to control certain aspects of its workhorse servlet. Directives can be used to have the workhorse servlet set its content type, import a package, control its output buffering and session management, extend a different superclass, and give special handling to errors. A directive can even specify the use of a non-Java scripting language.

The directive syntax requires a directive name along with an attribute name/value pair, all surrounded by <%@ %> tags. The quotes around the attribute value are mandatory:

<%@ directiveName attribName="attribValue" %>

The page directive allows the JSP to control the generated servlet through the setting of special attributes, as listed here:

contentType

Specifies the content type of the generated page. For example:

<%@ page contentType="text/plain" %>

The default content type is text/html; charset=8859_1.

import

Specifies a list of classes and packages the generated servlet should import. Multiple classes can be given in a comma-separated list. For example:

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

The implicit include list is java.lang.*,javax.servlet.*,javax.servlet.http.*,javax.servlet.jsp.*.

buffer

Specifies the minimum required size of the response buffer in kilobytes, similar to the servlet method setBufferSize( ). The value should be written as ##kb. A special value of none indicates that content should be passed directly to the underlying PrintWriter in the ServletResponse (which may or may not pass the content directly to the client). For example:

<%@ page buffer="12kb" %>

The default is 8kb.

autoFlush

Specifies if the buffer should be flushed when it's filled or if instead an IOException should be thrown. A true indicates to flush, a false indicates to throw. For example:

<%@ page autoFlush="true" %>

The default is true.

session

Indicates the page wants to have access to the user's session. A true puts the session variable in scope and may set a client cookie to manage the session. A false disables access to the session variable. For example:

<%@ page session="false" %>

The default is true.

errorPage

Specifies a page to display if a Throwable is thrown from within the JSP page and is not caught before reaching the server. This proves useful because it's difficult to do try/catch blocks when writing JSP pages. For example:

<%@ page errorPage="/error.jsp" %>

The default behavior is implementation dependent. The path is context relative, so you don't need to worry about prepending the current context path. The target may be a JSP but doesn't have to be. If the target is a servlet, the servlet may retrieve the Throwable as the request attribute javax.servlet.jsp.jspException.

isErrorPage

Indicates the page is intended to be used as the target of an errorPage. If the value is true the page can access an implicit variable named exception to retrieve the Throwable.

language

Specifies the scripting language used in the code sections of the page. The language used must interact with Java well enough to expose the necessary Java objects to the script environment. For example:

<%@ page language="javascript" %>

The default is java, the only language blessed by the specification.

18.4.1 Using Directives

Example 18-4 shows a JSP page named errorMaker.jsp that uses several directives. First it sets the page directive session attribute to false because the page doesn't use the session object and there's no need for the server to create a session needlessly. Then it sets the errorPage attribute to /errorTaker.jsp so if the page throws an uncaught exception the errorTaker.jsp page will handle the display of the error message. The body of the page is simple. It throws an exception to trigger the errorPage behavior. (We'll talk about why it uses the if check a little later.)

Example 18-4. Born to Be Bad
<%-- errorMaker.jsp --%> <%@ page session="false" %>             <%-- Don't send needless cookies --%> <%@ page errorPage="/errorTaker.jsp" %> <%-- General error handling page --%> <%-- All we're good for is throwing an exception --%> <%   if (System.currentTimeMillis() > 0) {     throw new Exception("oops");   } %>

The errorTaker.jsp page is shown in Example 18-5. It sets the page directive isErrorPage attribute to true to indicate this page handles errors, and it uses the import attribute to import the com.oreilly.servlet classes. The JSP uses a scriptlet to set the status code of the response to 500, then it writes the body of the page with the exception class name, a stack trace, and a message suggesting the user contact the webmaster to report the problem.

Example 18-5. And Your Problem Is...
<%-- errorTaker.jsp --%> <%@ page isErrorPage="true" %> <%@ page import="com.oreilly.servlet.*" %> <% response.setStatus(500); %> <HTML> <HEAD><TITLE>Error: <%= exception.getClass().getName() %></TITLE></HEAD> <BODY> <H1> <%= exception.getClass().getName() %> </H1> We encountered an error while executing your page: <PRE> <%= ServletUtils.getStackTraceAsString(exception) %> </PRE> <% String name = request.getServerName(); %> Please contact <A HREF="mailto:webmaster@<%= name %>">webmaster@<%= name %></A> to report the problem. </BODY> </HTML>

On any request to errorMaker.jsp, an exception is thrown, control is transferred to errorTaker.jsp, and errorTaker.jsp displays a nice error-reporting page. See Figure 18-3.

Figure 18-3. A customizable error page

So why did we have the System.currentTimeMillis( ) call in errorMaker.jsp ? That stems from the fact that JSP pages are required to preserve all whitespace from the body text of the document. This allows JSP to be used to create not only HTML but also XML, where whitespace can be very important. Unfortunately, preserving all whitespace means that the simple scriptlet:

<% throw new Exception("oops"); %>

must generate code to print a new line after the throw code that can never be reached! Compiling this scriptlet on Tomcat generates this error message:

org.apache.jasper.JasperException: Unable to compile class for   JSPC:\engines\jakarta-tomcat\work\localhost_8080%2Fjsp\   _0002ferrorMaker_0002ejsperrorMaker_jsp_3.java:75: Statement not reached.                 out.write("\r\n");                 ^

By adding the check as to whether System.currentTimeMillis( ) is greater than zero, the compiler assumes there's a possibility the exception won't be thrown and thus there's no compile error. Similar problems happen with return and throw statements inside scriptlets.

In fact, there are many such "gotchas" when using scriptlets with JSP. If you accidentally write a scriptlet instead of an expression (by forgetting the equals sign), declare a static variable inside a scriptlet (where statics aren't allowed), forget a semicolon (they're not needed in expressions but are needed in scriptlets), or write anything but perfect Java code, you're likely to get a confusing error message because the compiler is acting on the generated Java code, not on the JSP file. To demonstrate the problem, picture if <%= name %> were replaced by <% name %> in errorTaker.jsp. Tomcat generates this error:

org.apache.jasper.JasperException: Unable to compile class for   JSPC:\engines\jakarta-tomcat\work\localhost_8080%2Fjsp\   _0002ferrorTaker_0002ejsperrorTaker_jsp_6.java:91: Class name not found.                  name                  ^

Debugging an error like this often requires a programmer to look at the generated code to reconstruct what caused the error.

18.4.2 Avoid Java Code in JSP Pages

Scriptlets, expressions, and declarations allow the placement of Java code within a JSP page. They are powerful tools, yet we discourage their use. Even in the hands of a skilled programmer, placing code in the page is "secondhand" programming. You're writing Java code but not directly, and when errors occur the extra level of indirection makes the problem hard to diagnose.

When put into the hands on nonprogrammers, the situation becomes even worse. The nonprogrammers must learn some amount of Java, a language not designed for scripting and not intended for nonprogrammers. A language like JavaScript simpler, more forgiving, and better known by web designers could work better than Java, but JavaScript support is nonstandard and not widely implemented.

And finally, it's a matter of design. Having designers and developers working on the same file creates a bottleneck and extra opportunities for error. The content and presentation should be separated. To enable this and to move Java code out of the page, JSP allows the use of JavaBeans and custom tag libraries. We'll look at JavaBeans next.


Last updated on 3/20/2003
Java Servlet Programming, 2nd Edition, © 2001 O'Reilly

< BACKCONTINUE >


Java servlet programming
Java Servlet Programming (Java Series)
ISBN: 0596000405
EAN: 2147483647
Year: 2000
Pages: 223

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net