Skip Headers
Oracle® Containers for J2EE Support for JavaServer Pages Developer's Guide
10g Release 3 (10.1.3)
Part No. B14430-01
  Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
Next
Next
 

6 Working with JSP

This chapter discusses basic programming considerations for JSP pages, including JSP-servlet interaction and database access, with examples provided.

The following sections are included:

6.1 Before You Start

The following sections discuss some considerations you should be aware of before you begin coding or using JSP pages in the OC4J environment:

6.1.1 Understanding Application Root Functionality

The servlet specification (since Servlet 2.2) provides for each Web application to have its own servlet context. Each servlet context is associated with a directory path in the server file system, which is the base path for modules of the Web application. This is the application root.

Each Web application has its own application root. For a Web application in a standard servlet environment, servlets, JSP pages, and static files such as HTML files are all based out of this application root. (By contrast, in servlet 2.0 environments the application root for servlets and JSP pages is distinct from the document root for static files.)

Note that a servlet URL has the following general form:

http://host:port/contextpath/servletpath

When a servlet context is created, a mapping is specified between the application root and the context path portion of a URL. The servlet path is defined in the application web.xml file. The <servlet> element within web.xml associates a servlet class with a servlet name. The <servlet-mapping> element within web.xml associates a URL pattern with a named servlet. When a servlet is executed, the servlet container will compare a specified URL pattern with known servlet paths, and pick the servlet path that matches. See the Oracle Containers for J2EE Servlet Developer's Guide for more information.

For example, consider an application with the application root /home/dir/mybankapp/mybankwebapp, which is mapped to the context path /mybank. Further assume the application includes a servlet whose servlet path is loginservlet. You can invoke this servlet as follows:

http://host:port/mybank/loginservlet

The application root directory name itself is not visible to the user.

To continue this example for an HTML page in this application, the following URL points to the file /home/dir/mybankapp/mybankwebapp/dir/abc.html:

http://host:port/mybank/dir/abc.html

For each servlet environment there is also a default servlet context. For this context, the context path is simply "/", which is mapped to the default servlet context application root. For example, assume the application root for the default context is /home/dir/defaultapp/defaultwebapp, and a servlet with the servlet path myservlet uses the default context. Its URL would be as follows:

http://host:port/myservlet

The default context is also used if there is no match for the context path specified in a URL.

Continuing this example for an HTML file, the following URL points to the file /home/dir/defaultapp/defaultwebapp/dir2/def.html:

http://host:port/dir2/def.html

6.1.2 Understanding OC4J Classpath Functionality

The OC4J Web container uses standard locations on the Web server to look for translated JSP pages, as well as.class files and .jar files for any required classes such as JavaBeans. The container will find files in these locations without any Web server classpath configuration.

The locations for dependency classes are as follows and are relative to the application root:

/WEB-INF/classes/...
/WEB-INF/lib 

The location for JSP page implementation classes (translated pages) is as follows:

.../_pages/...

The /WEB-INF/classes directory is for individual Java .class files. You should store these classes in subdirectories under the classes directory, according to Java package naming conventions. For example, consider a JavaBean called LottoBean whose code defines it to be in the oracle.jsp.sample.lottery package. The Web container will look for LottoBean.class in the following location relative to the application root:

/WEB-INF/classes/oracle/jsp/sample/lottery/LottoBean.class

The lib directory is for JAR (.jar) files. Because Java package structure is specified in the JAR file structure, the JAR files are all directly in the lib directory, not in subdirectories. As an example, LottoBean.class might be stored in lottery.jar, located as follows relative to the application root:

/WEB-INF/lib/lottery.jar

The _pages directory is under the J2EE home directory in OC4J and depends on the value of the jsp-cache-directory configuration parameter. See "Generated Files and Locations" for information.


Important:

Implementation details, such as the default location of the _pages directory, are subject to change in future releases.

6.1.3 Packages Imported By Default in OC4J

The OC4J Web container by default imports the following packages into any JSP page, in accordance with the JSP specification. No page directive import settings are required to use these packages in a JSP:

javax.servlet.*
javax.servlet.http.*
javax.servlet.jsp.*

In previous releases, the following packages were also imported by default:

java.io.*
java.util.*
java.lang.reflect.*
java.beans.*

The default list of packages to import was reduced to minimize the chance of a conflict between any unqualified class name you might use and a class by the same name in any of the imported packages.

However, this might result in migration problems for applications you have used with previous versions of OC4J. Such applications might no longer compile successfully. If you need imports beyond the default list, you have two choices:

  • Specify additional package names or fully qualified class names in one or more page directive import settings. For more information, see the page directive under "Directives".

    For multiple pages, you can accomplish this through global includes functionality. See "Oracle JSP Global Includes".

  • Specify additional package names or fully qualified class names through the JSP extra_imports configuration parameter, or by using the ojspc -extraImports option for pretranslation. Syntax varies between OC4J configuration parameter settings and ojspc option settings, so refer to the following sections as appropriate:

6.1.4 JDK1.4 Issue: Classes Not in Packages Cannot Be Invoked

The Sun Microsystems JDK1.4 and JDK 1.5 ship with OC4J. As such, the following is something to consider if migrating from an earlier JDK.

As stated by Sun Microsystems, "The compiler now rejects import statements that import a type from the unnamed namespace." This was to address security concerns and ambiguities with previous JDK versions. Essentially, this means that you cannot invoke a class (a method of a class) that is not within a package. Any attempt to do so will result in a fatal error at compilation time.

This especially affects JSP developers who invoke JavaBeans from their JSP pages, as such beans are often outside of any package (although the JSP 2.0 specification now requires beans to be within packages, in order to satisfy the new compiler requirements).


Notes:

  • The javac -source compiler option is intended to allow JDK1.3. code to be processed seamlessly by the JDK1.4 compiler, but this option does not account for the "classes not in packages" issue.

  • Only the JDK1.4 and JDK1.5 compilers are supported and certified by OC4J. It is possible to specify an alternative compiler by adding a <java-compiler> element to the server.xml file, and this might provide a workaround for the "classes not in packages" issue, but no other compilers are certified or supported by Oracle for use with OC4J. (Furthermore, do not update the server.xml file directly in an Oracle Application Server environment. Use the Oracle Enterprise Manager 10g.)


For more information about JDK1.4 compatibility issues, refer to the following Web site:

http://java.sun.com/j2se/1.4/compatibility.html

In particular, click the link "Incompatibilities Between Java 2 Platform, Standard Edition, v.4.0 and v.3".

6.2 General JSP Programming Strategies

This portion discusses issues you should consider when programming JSP pages, regardless of the particular target environment. The following sections are included:


Note:

In addition to being aware of what is discussed in this section, you should be aware of JSP translation issues and behavior. See Chapter 5, "Understanding JSP Translation in OC4J".

6.2.1 Creating Traditional Versus Scriptless JSP

A major focus in JSP development has been on the creation of "scriptless" JSPs - pages that do not include embedded Java scripting elements such as scriptlets or runtime expressions. Scriptless JSPs offer a number of advantages over traditional script-based JSP development:

  • Removal of JSP scriptlets and expressions from JSP pages

  • Division of labor between JSP authors and Java developers. core philosophy of JSP has always been the division of labor and skills between JSP page authors, who are responsible for creating the HTML and JSP markup that comprises a JSP page, and Java developers, who are responsible for implementing the Java components that provide the processing logic.

  • Cleaner, more readable JSP

  • Ease of maintenance

The sample JSP code is an example of a scriptless JSP.

Since JSP 1.1, page authors have been able to create largely Java-free pages that utilize standard action tags and custom tags to access the Java functionality provided through JavaBeans and tag handler instances. However, creating truly scriptless pages presented a number of challenges, including limits on data access and the complexity of creating custom tag handler classes.

The JSP 2.0 release dramatically simplifies scriptless page authoring with a number of major enhancements. Among these is the full integration of the expression language (EL) functionality into the JSP specification, giving the EL access to all JSP page context objects, variables and request parameters, as well as JavaBean properties and collection elements. With the EL, you can access and manipulate application data without having to use Java scriptlets or expressions. See "Simplified JSP Authoring with the Expression Language" for more on the expression language.

It is also now much easier to create and use custom tags in your JSP pages. The JavaServer Pages Standard Tag Library (JSTL) provides a number of tag libraries that encapsulate much of the functionality most often needed by JSP authors. Creating custom tag handlers has been greatly simplified with the new SimpleTag interface. In fact, JSP authors can now create completely Java-free tag libraries using tag files, which are written completely in JSP syntax.

Note that JSP 2.0 provides backward compatibility with JSP 1.x, meaning that Java scripting elements can be used in pages written in JSP 2.0 syntax.

6.2.2 Using JavaBeans Versus Scriptlets

A key advantage of JavaServer Pages technology is the ability to separate the Java code containing the business logic and determining the dynamic content from the HTML code containing the request processing, presentation logic, and static content. This separation allows HTML experts to focus on presentation, while Java experts focus on business logic in JavaBeans that are called from the JSP page.

A typical JSP page will have only brief snippets of Java code, usually for Java functionality for request processing or presentation. Data access, such as in the runQuery() method in the sample, is usually more appropriate in a JavaBean. However, the formatResult() method in the sample, which formats the output, is more appropriate for the JSP page itself.

6.2.3 Using Static Includes Versus Dynamic Includes

You have two options for including JSP pages in a JSP page.

The include directive, described in "Directives", makes a copy of the included page and copies it into a JSP page (the "including page") during translation. This is known as a static include (or translate-time include) and uses the following syntax:

<%@ include file="/jsp/userinfopage.jsp" %>

The <jsp:include> tag, described in "Standard JSP Action Tags", dynamically includes output from the included page within the output of the including page during execution. This is known as a dynamic include (or runtime include) and uses the following syntax:

<jsp:include page="/jsp/userinfopage.jsp" flush="true" />

For those familiar with C syntax, a static include is comparable to a #include statement. A dynamic include is similar to a function call. They are both useful, but serve different purposes.


Note:

You can use static includes and dynamic includes only between pages in the same servlet context.

6.2.3.1 Logistics of Static Includes

A static include increases the size of the generated code for the including JSP page. It is as though the text of the included page is physically copied into the including page, at the point of the include directive, during translation. If a page is included multiple times within an including page, multiple copies are made.

A JSP page that is statically included is not required to be an independent, translatable entity. It simply consists of text that will be copied into the including page. The including page, with the included text copied in, must then be translatable. And, in fact, the including page does not have to be translatable prior to having the included page copied into it. A sequence of statically included pages can be fragments unable to stand on their own.

6.2.3.2 Logistics of Dynamic Includes

A dynamic include does not significantly increase the size of the generated code for the including page, although method calls, such as to the request dispatcher, will be added. The dynamic include results in runtime processing being switched from the including page to the included page, as opposed to the text of the included page being physically copied into the including page.

A dynamic include does increase processing overhead, with the necessity of the additional call to the request dispatcher.

A page that is dynamically included must be an independent entity, able to be translated and executed on its own. Likewise, the including page must be independent as well, able to be translated and executed without the dynamic include.

6.2.3.3 Advantages, Disadvantages, and Typical Uses of Dynamic and Static Includes

Static includes affect page size; dynamic includes affect processing overhead. Static includes avoid the overhead of the request dispatcher that a dynamic include necessitates, but may be problematic where large files are involved. (The service method of the generated page implementation class has a 64 KB size limit.)

Overuse of static includes can also make debugging your JSP pages difficult, making it harder to trace program execution. Avoid subtle interdependencies between your statically included pages.

Static includes are typically used to include small files whose content is used repeatedly in multiple JSP pages. For example:

  • Statically include a logo or copyright message at the top or bottom of each page in your application.

  • Statically include a page with declarations or directives, such as imports of Java classes, that are required in multiple pages.

  • Statically include a central "status checker" page from each page of your application. (See "Monitoring Your JSP Application".)

Dynamic includes are useful for modular programming. You may have a page that sometimes executes on its own but sometimes is used to generate some of the output of other pages. Dynamically included pages can be reused in multiple including pages without increasing the size of the including pages

6.2.4 Monitoring Your JSP Application

For general management or monitoring of your JSP application, it might be useful to use a central "checker" page that you include from each page in your application. A central checker page could accomplish tasks such as the following during execution of each page:

  • Check session status.

  • Check login status, such as checking the cookie to see if a valid login has been accomplished.

  • Check usage profile if a logging mechanism has been implemented to tally events of interest, such as mouse clicks or page visits.

There are many more possible uses as well.

As an example, consider a session checker class, MySessionChecker, that implements the HttpSessionBindingListener interface.

public class MySessionChecker implements HttpSessionBindingListener
{
   ...
   
   valueBound(HttpSessionBindingEvent event)
   {...}
   
   valueUnbound(HttpSessionBindingEvent event)
   {...}
   
   ...
}

You can create a checker page, suppose centralcheck.jsp, that contains something like the following:

<jsp:useBean id="sessioncheck" class="MySessionChecker" scope="session" />

In any page that includes centralcheck.jsp, the servlet container will call the valueUnbound() method implemented in the MySessionChecker class as soon as sessioncheck goes out of scope at the end of the session. Presumably this is to manage session resources. You could include centralcheck.jsp at the end of each JSP page in your application.

6.2.5 Managing Heavy Static Content or Tag Library Usage

JSP pages with large amounts of static content (essentially, large amounts of HTML code without content that changes at runtime) might result in slow translation and execution.

There are two primary workarounds for this, either of which will speed translation:

  • Put the static HTML into a separate file and use a jsp:include tag to include its output in the JSP page output at runtime. See "Standard JSP Action Tags" for information about the jsp:include tag.


Important:

A static include directive would not work. It would result in the included file being included at translation-time, with its code being effectively copied back into the including page. This would not solve the problem.

  • Put the static HTML into a Java resource file.

    The JSP translator will do this for you if you enable the external_resource configuration parameter. This parameter is documented in "Summary of JSP Configuration Parameters".

    For pretranslation, the -extres option of the ojspc tool offers equivalent functionality.


Note:

Putting static HTML into a resource file might result in a larger memory footprint than the jsp:include workaround mentioned above, because the page implementation class must load the resource file whenever the class is loaded.

Another possible problem with JSP pages that have large static content, or more commonly with JSP pages that have a great deal of tag library usage, is that most (if not all) JVMs impose a 64 KB size limit on the code within any single method. Although javac would be able to compile it, the JVM would be unable to execute it. Depending on the implementation of the JSP translator, this might become an issue for a JSP page because generated Java code from essentially the entire JSP page source file goes into the service method of the page implementation class. Java code is generated to output the static HTML to the browser, and Java code from any scriptlets is copied directly.

Similarly, it is possible for the Java scriptlets in a JSP page to be large enough to create a size limit problem in the service method. If there is enough Java code in a page to create a problem, however, then the code should be moved into JavaBeans.

If a large amount of tag library usage results in a size limit problem for a JSP page, a common solution is to break the page into multiple pages and use jsp:include tags as appropriate.

6.2.6 Using Method Variable Declarations Versus Member Variable Declarations

In "Scripting Elements", it is noted that JSP <%! ... %> declarations are used to declare member variables, while method variables must be declared in <% ... %> scriptlets.

Be careful to use the appropriate mechanism for each of your declarations, depending on how you want to use the variables:

  • A variable that is declared in <%! ... %> JSP declaration syntax is declared at the class level in the page implementation class that is generated by the JSP translator. In this case, if declaring an object instance, the object can be accessed simultaneously from multiple requests. Therefore, the object must be thread-safe, unless isThreadSafe="false" is declared in a page directive.

  • A variable that is declared in <% ... %> JSP scriptlet syntax is local to the service method of the page implementation class. Each time the method is called, a separate instance of the variable or object is created, so there is no need for thread safety.

Consider the following example, decltest.jsp:

<HTML>
<BODY>
<% double f2=0.0; %>
<%! double f=0.0; %>
Variable declaration test.
</BODY>
</HTML>

This results in something like the following code in the page implementation class:

package ...;
import ...;

public class decltest extends ... {
   ...

   // ** Begin Declarations
   double f=0.0;                  // *** f declaration is generated here ***
   // ** End Declarations

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

      try {
         out.println( "<HTML>");
         out.println( "<BODY>");
         double f2=0.0;      // *** f2 declaration is generated here ***
         out.println( "");
         out.println( "");
         out.println( "Variable declaration test.");
         out.println( "</BODY>");
         out.println( "</HTML>");
         out.flush();
      }
      catch( Exception e) {
         try {
            if (out != null) out.clear();
         }
         catch( Exception clearException) {
         }
      finally {
         if (out != null) out.close();
      }
   }
}


Note:

This code is provided for conceptual purposes only. Most of the class is deleted for simplicity, and the actual code of a page implementation class generated by the JSP translator would differ somewhat.

6.2.7 Working with Page Directives

This section discusses the following page directive characteristics:

  • A page directive is static and takes effect during translation. You cannot specify parameter settings to be evaluated at runtime.

  • Java import settings in page directives are cumulative within a JSP page or translation unit.

6.2.7.1 Page Directives Are Static

A page directive is static; it is interpreted during translation. You cannot specify dynamic settings to be interpreted at runtime. Consider the following examples.

6.2.7.1.1 Example

The following page directive is valid.

<%@ page contentType="text/html; charset=EUCJIS" %>
6.2.7.1.2 Example 2

The following page directive is not valid and will result in an error. (EUCJIS is hard-coded here, but the example also holds true for any character set determined dynamically at runtime.)

<% String s="EUCJIS"; %>
<%@ page contentType="text/html; charset=<%=s%>" %>

For some page directive settings there are workarounds. Reconsidering the second example, there is a setContentType() method that allows dynamic setting of the content type.

6.2.7.2 Duplicate Settings of Page Directive Attributes Are Disallowed

The JSP specification states that a Web container must verify that directive attributes, with the exception of the page directive import attribute, are not re-set with different values within a single JSP translation unit (a JSP page plus anything it includes through include directives).

For backward compatibility to the JSP . standard, where duplicate settings of directive attributes are allowed, OC4J provides the forgive_dup_dir_attr configuration parameter. In JSP 2.0, you only need to set this parameter when the different attributes have different values. See "Summary of JSP Configuration Parameters" for information about this parameter. You might have previously coded a page with multiple included segments that all set the page directive language attribute to "java", for example.

For clarity, be aware of the following points.

  • The JSP specification allows multiple page directives, as long as they set different attributes.

    This example is valid:

    <%@ page buffer="none" %>
    <%@ page session="true" %>
    
    

    or:

    ------------------------------
    <%@ page buffer="0kb" %>
    <%@ include file="b.jsp" %>
    ------------------------------
    ------------------------------
    b.jsp
    <%@ page session="false" %>
    ------------------------------
    
    

    However, this example would require that the forgive_dup_dir_attr parameter be set.

    <%@ page buffer="none" %>
    <%@ page buffer="0kb" %>
    
    

    or:

    <%@ page buffer="none" buffer="0kb" %>
    
    

    or:

    ------------------------------
    <%@ page buffer="0kb" %>
    <%@ include file="b.jsp" %>
    ------------------------------
    ------------------------------
    b.jsp
    <%@ page buffer="3kb" %>
    ------------------------------
    
    
  • A translation unit consists of a JSP page plus anything it includes through include directives, but not pages it includes through jsp:include tags. Pages included through jsp:include tags are dynamically included at runtime, not statically included during translation. See "Using Static Includes Versus Dynamic Includes" for more information.

    Therefore, the following is okay:

    ------------------------------
    <%@ page buffer="0kb" %>
    <jsp:include page="b.jsp" />
    ------------------------------
    ------------------------------
    b.jsp
    <%@ page buffer="3kb" %>
    ------------------------------
    
    
  • As noted in the opening paragraph above, the page directive import attribute is exempt from the limitation against duplicate attribute settings.

6.2.8 Workarounds for the 64K Size Limit for Generated Methods

The Java Virtual Machine (JVM) limits the amount of code to 64K (65536 bytes) per Java method. If your application uses large JSPs, it is possible to exceed this limit during runtime. As a general rule, keep the file size of JSPs to a minimum. If your JSP uses tag libraries heavily, enable the Applications->JSP Container Properties->Reduce Code Size for Custom Tags property (or the reduce_tag_code configuration parameter in global-web-application.xml) to reduce the size of generated code for custom tag usage. Note that this may impact JSP compilation performance.

6.2.9 Following JSP File Naming Conventions

The file name extension .jsp for JSP pages is required by the servlet specification. The servlet 2.3 specification does not, however, distinguish between complete pages that are independently translatable and page segments that are not (such as files brought in through an include directive).

The JSP 2.0 specification recommends the following:

  • Use the .jsp extension for top-level pages, dynamically included pages, and pages that are forwarded to—pages that are translatable on their own.

  • Do not use .jsp for page segments brought in through include directives—files that are not translatable on their own. No particular extension is mandated for such files, but .jsph, .jspf, or .jsf is recommended.

6.2.10 Understanding JSP Preservation of White Space and Use with Binary Data

Web containers generally preserve source code white space, including carriage returns and linefeeds, in what is output to the browser. Insertion of such white space might not be what the developer intended, and typically makes JSP technology a poor choice for generating binary data.

6.2.10.1 White Space Examples

The following two JSP pages produce different HTML output, due to the use of carriage returns in the source code.

6.2.10.1.1 Example : No Carriage Returns

The following JSP page does not have carriage returns after the Date() and getParameter() calls. (The third and fourth lines, starting with the Date() call, actually form a single wraparound line of code.)

nowhitsp.jsp:

<HTML>
<BODY>
<%= new java.util.Date() %> <% String user=request.getParameter("user"); %> <%= (user==null) ? "" : user %>
<B>Enter name:</B>
<FORM METHOD=get>
<INPUT TYPE="text" NAME="user" SIZE=5>
<INPUT TYPE="submit" VALUE="Submit name">
</FORM>
</BODY>
</HTML>

This code results in the following HTML output to the browser. Note that there are no blank lines after the date.

<HTML>
<BODY>
Tue May 30 20:07:04 PDT 2000  
<B>Enter name:</B>
<FORM METHOD=get>
<INPUT TYPE="text" NAME="user" SIZE=5>
<INPUT TYPE="submit" VALUE="Submit name">
</FORM>
</BODY>
</HTML>
6.2.10.1.2 Example 2: Carriage Returns

The following JSP page does include carriage returns after the Date() and getParameter() calls.

whitesp.jsp:

<HTML>
<BODY>
<%= new java.util.Date() %>
<% String user=request.getParameter("user"); %>
<%= (user==null) ? "" : user %>
<B>Enter name:</B>
<FORM METHOD=get>
<INPUT TYPE="text" NAME="user" SIZE=5>
<INPUT TYPE="submit" VALUE="Submit name">
</FORM>
</BODY>
</HTML>

This code results in the following HTML output to the browser.

<HTML>
<BODY>
Tue May 30 20:9:20 PDT 2000


<B>Enter name:</B>
<FORM METHOD=get>
<INPUT TYPE="text" NAME="user" SIZE=5>
<INPUT TYPE="submit" VALUE="Submit name">
</FORM>
</BODY>
</HTML>

6.2.10.2 Reasons to Avoid Binary Data in JSP Pages

For the following reasons, JSP pages are a poor choice for generating binary data. Generally, you should use servlets instead.

  • JSP implementations are not designed to handle binary data. There are no methods in the JspWriter class for writing raw bytes.

  • During execution, the Web container preserves white space. White space is sometimes unwanted, making JSP pages a poor choice for generating binary output (a .gif file, for example) to the browser or for other uses where white space is significant.

    Consider the following general example:

    ...
    <% response.getOutputStream().write(...binary data...) %>
    <% response.getOutputStream().write(...more binary data...) %>
    
    

    In this case, the browser will receive an unwanted newline character in the middle of the binary data or at the end, depending on the buffering of your output buffer. You can avoid this problem by not using a carriage return between the lines of code, but this is an undesirable programming style.


Note:

The preceding example is for illustrative purposes only and might not be portable to future Oracle JSP versions or other Web containers.

Trying to generate binary data in JSP pages largely misses the point of JSP technology anyway, which is intended to simplify the programming of dynamic textual content.

6.3 JSP Best Practices

The following sections discuss best practices to consider when developing JSP pages for deployment into OC4J.

6.3.1 Beware of HTTP Sessions

HTTP sessions add performance overhead to your Web applications due to the amount of memory used. Sessions are enabled in JSP by default.

6.3.1.1 Avoid Using HTTP Sessions If Not Required

Avoid using HTTP session objects if they are not required. If a JSP page does not require an HTTP session (essentially, does not require storage or retrieval of session attributes), then you can specify that no session is to be used. Specify this with a page directive such as the following:

<%@ page session="false" %>

This will improve the performance of the page by eliminating the overhead of session creation or retrieval.

Note that although servlets by default do not use a session, JSP pages by default do use a session.

6.3.1.2 Always Invalidate Sessions When No Longer In Use

If your JSPs do use HTTP sessions, ensure that you explicitly cancel each session using the javax.servlet.http.HttpSession.invalidate() method to release the memory occupied.The default session timeout for OC4J is 30 minutes. You can change this for a specific application by setting the <session-timeout> parameter in the <session-config> element of the application's web.xml file.

6.3.2 Pre-translate JSP Pages Using the ojspc Utility

You might consider using the ojspc utility to pretranslate JSP pages before deployment. This avoids the performance cost of translating pages as they are first accessed by users. See Chapter 4, "Precompiling JSPs with ojspc" for details on using this utility.

6.3.3 Ensure Updated Objects Are Re-set on HTTP Sessions

When creating JSPs for distributable Web applications, ensure that updates to session objects are replicated in a clustered environment by coding your pages to re-set changed objects on the HTTP session.

OC4J will serialize session objects that are saved in the session; however, session objects are not re-serialized when changes are made to an object's data members, meaning that the updated session state will not be replicated. Note that this issue is not unique to JSP; for example, servlets must also re-set changed objects on the session.

Your JSPs should include scriplets that call setAttribute() on the HttpSession for each modifiable session attribute to ensure that the session state is replicated.

If using <jsp:useBean> tags to create session-scope beans, call setAttribute() to re-set updated beans on the session. Properties set on the bean when the bean is created are set in the session; however, updates to bean property values are not.

6.3.4 Un-Buffer JSP Pages

Unbuffer JSP pages. By default, a JSP page uses an area of memory known as a page buffer. This buffer (8 KB by default) is required if the page uses dynamic globalization support content type settings, forwards, or error pages. If it does not use any of these features, you can disable the buffer in a page directive:

<%@ page buffer="none" %>

This will improve the performance of the page by reducing memory usage and saving the output step of copying the buffer.

6.3.5 Forward to JSP Pages Instead of Using Redirects

You can pass control from one JSP page to another using one of two options: Including a <jsp:forward> standard action tag or passing the redirect URL to response.sendRedirect() in a scriptlet.

The <jsp:forward> option is faster and more efficient. When you use this standard action, the forwarded target page is invoked internally by the JSP runtime, which continues to process the request. The browser is totally unaware that the forward has taken place, and the entire process appears to be seamless to the user.

When you use sendRedirect(), the browser actually has to make a new request to the redirected page. The URL shown in the browser is changed to the URL of the redirected page. In addition, all request scope objects are unavailable to the redirected page because redirect involves a new request.

Use a redirect only if you want the URL to reflect the actual page that is being executed in case the user wants to reload the page.

6.3.6 Hide JSP Pages from Direct Invocation to Limit Access

There are situations, particularly in an architecture such as Model-View-Controller (MVC), where you would want to ensure that some JSP pages are accessible only to the application itself and cannot be invoked directly by users.

As an example, assume that the front-end or "view" page is index.jsp. The user starts the application through a URL request that goes directly to that page. Further assume that index.jsp includes a second page, included.jsp, and forwards to a third page, forwarded.jsp, and that you do not want users to be able to invoke these directly through a URL request.

A mechanism for this is to place included.jsp and forwarded.jsp in the application /WEB-INF directory. When located there, the pages cannot be directly invoked through URL request. Any attempt would result in an error report from the browser.

The page index.jsp would have the following statements:

<jsp:include page="WEB-INF/included.jsp"/>
...
<jsp:forward page="WEB-INF/forwarded.jsp"/>

The application structure would be as follows, including the standard classes directory for any servlets, JavaBeans, or other classes, and including the standard lib directory for any JAR files:

index.jsp
WEB-INF/
   web.xml
   included.jsp
   forwarded.jsp
   classes/
   lib/

6.3.7 Use JSP-Timeout for Efficient Memory Utilization

Set the jsp-timeout attribute of the <orion-web-app> element to an integer value, in seconds, after which any JSP page will be removed from memory if it has not been requested. This frees up resources in situations where some pages are called infrequently. The default value is 0, indicating no timeout. The <orion-web-app> element is found in the OC4J global-web-application.xml and orion-web.xml files. Modify the global-web-application.xml file to apply the timeout to all applications in an OC4J instance. To set configuration values to a specific application, set the file in the application-specific orion-web.xml file.

6.3.8 Package JSP Files In EAR File For Deployment

OC4J supports deployment of JSP pages by copying the files directly to the appropriate location. This is very useful when developing and testing the pages.

However, this practice is not recommended for releasing your JSP-based application for production. Always package JSP files in an Enterprise Archive (EAR) file to allow deployment in a standard manner and to allow deployment across multiple application servers.

6.4 Working with Servlets

Although coding JSP pages is convenient in many ways, some situations call for servlets. One example is when you are outputting binary data.

As such, it is sometimes necessary to go back and forth between servlets and JSP pages in an application. The following sections discuss how to accomplish this:

6.4.1 Invoking a Servlet from a JSP Page

As when invoking one JSP page from another, you can invoke a servlet from a JSP page through the jsp:include and jsp:forward action tags. (See "Standard JSP Action Tags".) Following is an example:

<jsp:include page="/servlet/MyServlet" flush="true" />

When this statement is encountered during page execution, the page buffer is output to the browser and the servlet is executed. When the servlet has finished executing, control is transferred back to the JSP page and the page continues executing. This is the same functionality as for jsp:include actions from one JSP page to another.

And as with jsp:forward actions from one JSP page to another, the following statement would clear the page buffer, terminate the execution of the JSP page, and execute the servlet:

<jsp:forward page="/servlet/MyServlet" />

6.4.2 Passing Data to a Servlet Invoked from a JSP Page

When dynamically including or forwarding to a servlet from a JSP page, you can use a jsp:param tag to pass data to the servlet (the same as when including or forwarding to another JSP page).

You can use a jsp:param tag within a jsp:include or jsp:forward tag. Consider the following example:

<jsp:include page="/servlet/MyServlet" flush="true" >
   <jsp:param name="username" value="Smith" />
   <jsp:param name="userempno" value="9876" />
</jsp:include>

For more information about the jsp:param tag, see "Standard JSP Action Tags".

Alternatively, you can pass data between a JSP page and a servlet through a JavaBean of appropriate scope or through attributes of the HTTP request object. Using attributes of the request object is discussed later, in "Passing Data Between a JSP Page and a Servlet".

6.4.3 Invoking a JSP Page from a Servlet

You can invoke a JSP page from a servlet through functionality of the standard javax.servlet.RequestDispatcher interface. Complete the following steps in your code to use this mechanism:

  1. Get a servlet context instance from the servlet instance:

    ServletContext sc = this.getServletContext();
    
    
  2. Get a request dispatcher from the servlet context instance, specifying the page-relative or application-relative path of the target JSP page as input to the getRequestDispatcher() method:

    RequestDispatcher rd = sc.getRequestDispatcher("/jsp/mypage.jsp");
    
    

    Prior to or during this step, you can optionally make data available to the JSP page through attributes of the HTTP request object. See "Passing Data Between a JSP Page and a Servlet" below for information.

  3. Invoke the include() or forward() method of the request dispatcher, specifying the HTTP request and response objects as arguments. For example:

    rd.include(request, response);
    
    

    or:

    rd.forward(request, response);
    
    

    The functionality of these methods is similar to that of jsp:include and jsp:forward tags. The include() method only temporarily transfers control; execution returns to the invoking servlet afterward.

    Note that the forward() method clears the output buffer.


    Note:

    The request and response objects would have been obtained earlier, using standard servlet functionality such as the doGet() method specified in the javax.servlet.http.HttpServlet class.

6.4.4 Passing Data Between a JSP Page and a Servlet

The preceding section, "Invoking a JSP Page from a Servlet", notes that when you invoke a JSP page from a servlet through the request dispatcher, you can optionally pass data through the HTTP request object. You can accomplish this using either of the following approaches:

  • You can append a query string to the URL when you obtain the request dispatcher, using "?" syntax with name=value pairs. For example:

    RequestDispatcher rd = 
           sc.getRequestDispatcher("/jsp/mypage.jsp?username=Smith");
    
    

    In the target JSP page (or servlet), you can use the getParameter() method of the implicit request object to obtain the value of a parameter set in this way.

  • You can use the setAttribute() method of the HTTP request object. For example:

    request.setAttribute("username", "Smith");
    RequestDispatcher rd = sc.getRequestDispatcher("/jsp/mypage.jsp");
    
    

    In the target JSP page or servlet, you can use the getAttribute() method of the implicit request object to obtain the value of a parameter set in this way.


    Note:

    You can use the mechanisms discussed in this section instead of the jsp:param tag to pass data from a JSP page to a servlet.

6.4.5 JSP-Servlet Interaction Samples

This section provides a JSP page and a servlet that use functionality described in the preceding sections. The JSP page Jsp2Servlet.jsp includes the servlet MyServlet, which includes another JSP page, welcome.jsp.

6.4.5.1 Code for Jsp2Servlet.jsp

<HTML>
<HEAD> <TITLE> JSP Calling Servlet Demo </TITLE> </HEAD>
<BODY>

<!-- Forward processing to a servlet -->
<% request.setAttribute("empid", "234"); %>
<jsp:include page="/servlet/MyServlet?user=Smith" flush="true"/>

</BODY>
</HTML>

6.4.5.2 Code for MyServlet.java

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.PrintWriter;
import java.io.IOException;

public class MyServlet extends HttpServlet {

    public void doGet (HttpServletRequest request,
                       HttpServletResponse response) 
      throws IOException, ServletException {
      PrintWriter out= response.getWriter(); 
      out.println("<B><BR>User:" + request.getParameter("user"));
      out.println
          (", Employee number:" + request.getAttribute("empid") + "</B>");
      this.getServletContext().getRequestDispatcher
                       ("/jsp/welcome.jsp").include(request, response);
    }
}

6.4.5.3 Code for welcome.jsp

<HTML>
<HEAD> <TITLE> The Welcome JSP  </TITLE> </HEAD>
<BODY>

<H3> Welcome! </H3>
<P><B> Today is <%= new java.util.Date() %>.  Have a nice day! </B></P>
</BODY>
</HTML>

6.5 Processing Runtime Errors

While a JSP page is executing and processing client requests, runtime errors can occur either inside the page or outside the page, such as in a called JavaBean. This section describes error processing mechanisms and provides an elementary example.

6.5.1 Servlet and JSP Runtime Error Mechanisms

This section describes mechanisms for handling runtime exceptions, including the use of JSP error pages.

6.5.1.1 General Servlet Runtime Error Mechanism

Any runtime error encountered during execution of a JSP page is handled through the standard Java exception mechanism in one of two ways:

  • You can catch and handle exceptions in a Java scriptlet within the JSP page itself, using standard Java exception-handling code.

  • Exceptions that you do not catch in the JSP page will result in forwarding of the request and uncaught exception, a java.lang.Throwable instance, to an error resource. This is the preferred way to handle JSP errors. In this case, the exception instance describing the error is stored in the request object through a setAttribute() call, using javax.servlet.jsp.jspException as the name.

You can specify the URL of an error resource by setting the errorPage attribute in a page directive in the originating JSP page. (For an overview of JSP directives, including the page directive, see "Directives".)

See the Sun Microsystems Java Servlet Specification, Version 2.4 for more information about default error resources.

6.5.1.2 JSP Error Pages

You have the option of using another JSP page as the error resource for runtime exceptions from an originating JSP page. A JSP error page must have a page directive setting isErrorPage="true". An error page defined in this way takes precedence over an error page declared in the web.xml file.

The java.lang.Throwable instance describing the error is accessible in the error page through the JSP implicit exception object. Only an error page can access this object. For information about JSP implicit objects, including the exception object, see "Implicit Objects".

Be aware that if an originating JSP page has a page directive with autoFlush="true" (the default setting), and the contents of the JspWriter object from that page have already been flushed to the response output stream, then any further attempt to forward an uncaught exception to any error page might not be able to clear the response. Some of the response might have already been received by the browser.

See "JSP Error Page Example" below for an example of error page usage.

6.5.2 JSP Error Page Example

The following example, nullpointer.jsp, generates an error and uses an error page, myerror.jsp, to output contents of the implicit exception object.

6.5.2.1 Code for nullpointer.jsp

<HTML>
<BODY>
<%@ page errorPage="myerror.jsp" %>
Null pointer is generated below:
<%
   String s=null;
   s.length();
%>
</BODY>
</HTML>

6.5.2.2 Code for myerror.jsp

<HTML>
<BODY>
<%@ page isErrorPage="true" %>
Here is your error:
<%= exception %>
</BODY>
</HTML>

This example results in the following output:

Description of myerror.gif follows
Description of the illustration myerror.gif


Note:

The line "Null pointer is generated below:" in nullpointer.jsp is not output when processing is forwarded to the error page. This shows the difference between jsp:include and jsp:forward functionality. With jsp:forward, the output from the "forward-to" page replaces the output from the "forward-from" page.