Skip Headers
Oracle® Application Server Containers for J2EE Support for JavaServer Pages Developer's Guide
10g Release 2 (10.1.2)
B14014-02
  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
 

4 Basic Programming Considerations

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

The following sections are included:

JSP-Servlet Interaction

Although coding JSP pages is convenient in many ways, some situations call for servlets. One example is when you are outputting binary data, as discussed in "Reasons to Avoid Binary Data in JSP Pages".

Therefore, 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:

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 Actions: JSP 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" />

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 Actions: JSP 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".

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.

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.

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.

Code for Jsp2Servlet.jsp

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

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

</BODY>
</HTML>

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);
    }
}

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>

JSP Data-Access Support and Features

The following sections discuss OC4J JSP and Oracle features to consider when accessing data:

Introduction to JSP Support for Data Access

Because the JDBC API is simply a set of Java interfaces, JavaServer Pages technology directly supports its use within JSP scriptlets.

Oracle JDBC provides several driver alternatives: 1) the JDBC OCI driver for use with an Oracle client installation; 2) a 100%-Java JDBC Thin driver that can be used in essentially any client situation, including applets; 3) a JDBC server-side Thin driver to access one Oracle Database instance from within another Oracle Database instance; and 4) a JDBC server-side internal driver to access the database within which the Java code is running, such as from a Java stored procedure. It is assumed that you are already at least somewhat familiar with JDBC basics, but you can refer to the Oracle Database JDBC Developer's Guide and Reference.

The OC4J JSP container also supports EJB calls.

Additionally, there are SQL tags in the JavaServer Pages Standard Tag Library (JSTL), and JavaBeans and custom SQL tags supplied with OC4J. These are all documented in the Oracle Application Server Containers for J2EE JSP Tag Libraries and Utilities Reference.

JSP Data-Access Sample Using JDBC

The following example creates a query dynamically from search conditions the user enters through an HTML form (typed into a box, and entered with an Ask Oracle button). To perform the specified query, it uses JDBC code in a method called runQuery() that is defined in a JSP declaration. It also defines a method, formatResult(), within the JSP declaration to produce the output. The runQuery() method uses the scott schema with password tiger.

The HTML INPUT tag specifies that the string entered in the form be named cond. Therefore, cond is also the input parameter to the getParameter() method of the implicit request object for this HTTP request, and the input parameter to the runQuery() method (which puts the cond string into the WHERE clause of the query).


Notes:

  • Another approach to this example would be to define the runQuery() method in <%...%> scriptlet syntax instead of <%!...%> declaration syntax.

  • This example uses the JDBC OCI driver, which requires an Oracle client installation. If you want to run this sample, use an appropriate JDBC driver and connection string.


<%@ page language="java" import="java.sql.*" %>
<HTML>
<HEAD> <TITLE> The JDBCQuery JSP  </TITLE> </HEAD>
<BODY BGCOLOR="white">
<% String searchCondition = request.getParameter("cond"); 
   if (searchCondition != null) { %>
      <H3> Search results for  <I> <%= searchCondition %> </I> </H3>
      <B> <%= runQuery(searchCondition) %> </B> <HR><BR>
<% }  %>
<B>Enter a search condition:</B>
<FORM METHOD="get"> 
<INPUT TYPE="text" NAME="cond" SIZE=30>
<INPUT TYPE="submit" VALUE="Ask Oracle");
</FORM>
</BODY>
</HTML>
<%-- Declare and define the runQuery() method. --%>
<%! private String runQuery(String cond) throws SQLException {
     Connection conn = null; 
     Statement stmt = null; 
     ResultSet rset = null; 
     try {
        DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
        conn = DriverManager.getConnection("jdbc:oracle:oci:@",
                                           "scott", "tiger");
        stmt = conn.createStatement();
        // dynamic query
        rset = stmt.executeQuery ("SELECT ename, sal FROM scott.emp "+ 
                           (cond.equals("") ? "" : "WHERE " + cond ));
       return (formatResult(rset));
     } catch (SQLException e) { 
         return ("<P> SQL error: <PRE> " + e + " </PRE> </P>\n");
     } finally {
         if (rset!= null) rset.close(); 
         if (stmt!= null) stmt.close();
         if (conn!= null) conn.close();
     }
  }
  private String formatResult(ResultSet rset) throws SQLException {
    StringBuffer sb = new StringBuffer();
    if (!rset.next())
      sb.append("<P> No matching rows.<P>\n");
    else {  sb.append("<UL>"); 
            do {  sb.append("<LI>" + rset.getString(1) + 
                            " earns $ " + rset.getInt(2) + ".</LI>\n");
            } while (rset.next());
           sb.append("</UL>"); 
    }
    return sb.toString();
  }
%>

Figure 4-1 illustrates sample output for the following input:

sal >= 2500 AND sal < 5000

Figure 4-1 Sample Query Results

Description of Figure 4-1  follows
Description of "Figure 4-1 Sample Query Results"

Use of JDBC Performance Enhancement Features

JSP applications in OC4J can use features for the following performance enhancements, supported through Oracle JDBC extensions:

  • Caching database connections

  • Caching JDBC statements

  • Batching update statements

  • Prefetching rows during a query

  • Caching rowsets

Most of these performance features are supported by the Oracle ConnBean and ConnCacheBean data-access JavaBeans (but not by DBBean). These beans are described in the Oracle Application Server Containers for J2EE JSP Tag Libraries and Utilities Reference.

Database Connection Caching

Creating a new database connection is an expensive operation that you should avoid whenever possible. Instead, use a cache of database connections. A JSP application can get a logical connection from a pre-existing pool of physical connections, and return the connection to the pool when done.

You can create a connection pool at any one of the four JSP scopes—application, session, page, or request. It is most efficient to use the maximum possible scope—application scope if that is permitted by the Web server, or session scope if not.

The Oracle JDBC connection caching scheme, built upon standard connection pooling as specified in the JDBC 2.0 standard extensions, is implemented in the ConnCacheBean data-access JavaBean provided with OC4J. Alternatively, you can use standard data-source connection pooling functionality, which is supported by the ConnBean data-access JavaBean. These beans are described in the Oracle Application Server Containers for J2EE JSP Tag Libraries and Utilities Reference.

For information about the Oracle JDBC connection caching scheme, see the Oracle Database JDBC Developer's Guide and Reference.

JDBC Statement Caching

Statement caching, an Oracle JDBC extension, improves performance by caching executable statements that are used repeatedly within a single physical connection, such as in a loop or in a method that is called repeatedly. When a statement is cached, the statement does not have to be re-parsed, the statement object does not have to be re-created, and parameter size definitions do not have to be recalculated each time the statement is executed.

The Oracle JDBC statement caching scheme is implemented in the ConnBean and ConnCacheBean data-access JavaBeans that are provided with OC4J. Each of these beans has a stmtCacheSize property that can be set through a jsp:setProperty tag or the bean setStmtCacheSize() method. The beans are described in the Oracle Application Server Containers for J2EE JSP Tag Libraries and Utilities Reference.

For information about the Oracle JDBC statement caching scheme, see the Oracle Database JDBC Developer's Guide and Reference.


Important:

Statements can be cached only within a single physical connection. When you enable statement caching for a connection cache, statements can be cached across multiple logical connection objects from a single pooled connection object, but not across multiple pooled connection objects.

Update Batching

The Oracle JDBC update batching feature associates a batch value (limit) with each prepared statement object. With update batching, instead of the JDBC driver executing a prepared statement each time its execution method is called, the driver adds the statement to a batch of accumulated execution requests. The driver will pass all the operations to the database for execution once the batch value is reached. For example, if the batch value is 10, then each batch of ten operations will be sent to the database and processed in one trip.

OC4J supports Oracle JDBC update batching directly, through the executeBatch property of the ConnBean data-access JavaBean. You can set this property through a jsp:setProperty tag or through the setter method of the bean. If you use ConnCacheBean instead, you can enable update batching through Oracle JDBC functionality in the connection and statement objects you create. These beans are described in the Oracle Application Server Containers for J2EE JSP Tag Libraries and Utilities Reference.

For more information about Oracle JDBC update batching, see the Oracle Database JDBC Developer's Guide and Reference.

Row Prefetching

For the population of query result sets, the Oracle JDBC row prefetching feature enables you to determine the number of rows to prefetch into the client during each trip to the database. This reduces the number of round-trips to the server.

OC4J supports Oracle JDBC row prefetching directly, through the preFetch property of the ConnBean data-access JavaBean. You can set this property through a jsp:setProperty tag or through the setter method of the bean. If you use ConnCacheBean instead, you can enable row prefetching through Oracle JDBC functionality in the connection and statement objects you create. These beans are described in the Oracle Application Server Containers for J2EE JSP Tag Libraries and Utilities Reference.

For more information about Oracle JDBC row prefetching, see the Oracle Database JDBC Developer's Guide and Reference.

Rowset Caching

A cached rowset provides a disconnected, serializable, and scrollable container for retrieved data. This feature is useful for small sets of data that do not change often, particularly when the client requires frequent or continued access to the information. By contrast, using a normal result set requires the underlying connection and other resources to be held. Be aware, however, that large cached rowsets consume a lot of memory on the application server.

In Oracle Database, the Oracle JDBC implementation provides a cached rowset implementation. If you are using an Oracle JDBC driver, use code inside a JSP page to create and populate a cached rowset, as follows:

CachedRowSet crs = new CachedRowSet();
crs.populate(rset); // rset is a previously created JDBC ResultSet object.

Once the rowset is populated, the connection and statement objects used in obtaining the original result set can be closed.

For more information about Oracle JDBC cached rowsets, see the Oracle Database JDBC Developer's Guide and Reference.

EJB Calls from JSP Pages

JSP pages can call EJBs to perform additional processing or data access. A typical application design uses JavaServer Pages as a front-end for the initial processing of client requests, with Enterprise JavaBeans being called to perform the work that involves reading from and writing to data sources. The following sections provide an overview of EJB usage:

Overview of Configuration and Deployment for EJBs

The configuration and deployment steps for calling EJBs from JSP pages are similar to the steps for calling EJBs from servlets, which are described in the Oracle Application Server Containers for J2EE Servlet Developer's Guide. These steps include the following:

  • Define an <ejb-ref> element in the application web.xml file for each EJB called from a JSP page.

  • Create an ejb-jar.xml deployment descriptor that contains an <enterprise-beans> element with appropriate subelements, such as <session> or <entity>, that specify the types of EJBs. Within these subelements, specify the name, class name, and other details for each called EJB.

  • Package the ejb-jar.xml file in the EJB archive. Deployment requirements are very similar to the requirements for servlets.

Code Steps and Approaches for EJB Calls

The key steps required for a JSP page to invoke an EJB are the following:

  1. Import the EJB package for the bean home and remote interfaces into each JSP page that makes EJB calls. Use a page directive for this.

  2. Use JNDI to look up the EJB home interface.

  3. Create the EJB remote object from the home.

  4. Invoke business methods on the remote object.

Because you can use almost any servlet code in a JSP page in the form of a scriptlet, one straightforward way to call EJBs from a JSP page is to use the same code in a scriptlet that you would use in a servlet. This is one way to accomplish steps 2, 3, and 4.

Alternatively, you can use tags from the EJB tag library provided with OC4J. This is described in the next section, "Use of the OC4J EJB Tag Library". These tags simplify the coding. Essentially, they allow you to treat Enterprise JavaBeans similarly to regular JavaBeans, which are commonly used in JSP pages.

Use of the OC4J EJB Tag Library

Refer to the preceding section, "Code Steps and Approaches for EJB Calls". As in that section, import the appropriate package in a page directive. Then use the OC4J EJB tags as follows:

  • Use a taglib directive to specify the tag prefix and the tag library descriptor (TLD) file that you will use.

  • For step 2 of the code steps, use an EJB useHome tag.

  • For step 3 of the code steps, you can use an EJB createBean tag inside an EJB useBean tag.

  • For step 4 of the code steps, the EJB iterate tag enables you to apply business methods to each member of a collection of EJB objects, usually returned by a find method.

For more information about the EJB tag library, including detailed tag syntax, see the Oracle Application Server Containers for J2EE JSP Tag Libraries and Utilities Reference.

Deployment requirements are the same for the tag library approach as for the scriptlet code approach. As with any tag library, the TLD and the library support classes (tag handler classes and tag-extra-info classes) must be made accessible to your application.

OracleXMLQuery Class

The oracle.xml.sql.query.OracleXMLQuery class is part of the Oracle Database XML-SQL utility for XML functionality in database queries. This class requires file xsu12.jar, which is also required for XML functionality in some of the custom tags and JavaBeans provided with OC4J. This file is provided with Oracle Database and Oracle Application Server.

For information about the OracleXMLQuery class and other XML-SQL utility features, refer to the Oracle XML Developer's Kit Programmer's Guide.

JSP Resource Management

The following sections discuss standard features and Oracle value-added features for resource management:

Standard Session Resource Management: HttpSessionBindingListener

A JSP page must appropriately manage resources acquired during its execution, such as JDBC connection, statement, and result set objects. The standard javax.servlet.http package provides the HttpSessionBindingListener interface and HttpSessionBindingEvent class to manage session-scope resources. Through this mechanism, a session-scope query bean could, for example, acquire a database cursor when the bean is instantiated and close it when the HTTP session is terminated. (The example in "JSP Data-Access Sample Using JDBC" opens and closes the connection for each query, which adds overhead.)

This section describes use of the HttpSessionBindingListener valueBound() and valueUnbound() methods.


Note:

The bean instance must register itself in the event notification list of the HTTP session object, but the jsp:useBean statement takes care of this automatically.

The valueBound() and valueUnbound() Methods

An object that implements the HttpSessionBindingListener interface can implement a valueBound() method and a valueUnbound() method, each of which takes an HttpSessionBindingEvent instance as input. These methods are called by the servlet container—the valueBound() method when the object is stored in the session, and the valueUnbound() method when the object is removed from the session or when the session reaches a timeout or becomes invalid. Usually, a developer will use valueUnbound() to release resources held by the object (in the example below, to release the database connection).

"JDBCQueryBean JavaBean Code" below provides a sample JavaBean that implements HttpSessionBindingListener and a sample JSP page that calls the bean.

JDBCQueryBean JavaBean Code

Following is the sample code for JDBCQueryBean, a JavaBean that implements the HttpSessionBindingListener interface. It uses the JDBC OCI driver for its database connection; use an appropriate JDBC driver and connection string if you want to run this example yourself.

JDBCQueryBean gets a search condition through the HTML request (as described in "UseJDBCQueryBean JSP Page"), executes a dynamic query based on the search condition, and outputs the result.

This class also implements a valueUnbound() method, as specified in the HttpSessionBindingListener interface, that results in the database connection being closed at the end of the session.

package mybeans;

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

public class JDBCQueryBean implements HttpSessionBindingListener
{
  String searchCond = "";
  String result = null;
  
  public void JDBCQueryBean() {
  }
  
  public synchronized String getResult() {
    if (result != null) return result;
    else return runQuery();
  }
  
  public synchronized void setSearchCond(String cond) {
    result = null;
    this.searchCond = cond;
  }
  
  private Connection conn = null;
  
  private String runQuery() {
    StringBuffer sb = new StringBuffer(); 
    Statement stmt = null; 
    ResultSet rset = null;
    try {
      if (conn == null) {
        DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
        conn = DriverManager.getConnection("jdbc:oracle:oci8:@",
                                           "scott", "tiger");

      }
      
      stmt = conn.createStatement();
      rset = stmt.executeQuery ("SELECT ename, sal FROM scott.emp "+ 
            (searchCond.equals("") ? "" : "WHERE " + searchCond ));
      result = formatResult(rset);
      return result;

    } catch (SQLException e) { 
      return ("<P> SQL error: <PRE> " + e + " </PRE> </P>\n");
    }
    finally {
      try {
        if (rset != null) rset.close();
        if (stmt != null) stmt.close();
      }
      catch (SQLException ignored) {}
    }
  }
  
  private String formatResult(ResultSet rset) throws SQLException  {
    StringBuffer sb = new StringBuffer();
    if (!rset.next())    
      sb.append("<P> No matching rows.<P>\n");
    else {  
      sb.append("<UL><B>"); 
      do {  sb.append("<LI>" + rset.getString(1) + 
            " earns $ " + rset.getInt(2) + "</LI>\n");
      } while (rset.next());
      sb.append("</B></UL>"); 
    }
    return sb.toString();
  }
  
  public void valueBound(HttpSessionBindingEvent event) {
    // do nothing -- the session-scope bean is already bound
  }
  
  public synchronized void valueUnbound(HttpSessionBindingEvent event) {
    try { 
      if (conn != null) conn.close();
    }
    catch (SQLException ignored) {}
  }
}


Note:

The preceding code serves as a sample only. This is not necessarily an advisable way to handle database connection pooling in a large-scale Web application.

UseJDBCQueryBean JSP Page

The following JSP page uses the JDBCQueryBean JavaBean defined in "JDBCQueryBean JavaBean Code" above, invoking the bean with session scope. It uses JDBCQueryBean to display employee names that match a search condition entered by the user.

JDBCQueryBean gets the search condition through the jsp:setProperty tag in this JSP page, which sets the searchCond property of the bean according to the value of the searchCond request parameter input by the user through the HTML form. The HTML INPUT tag specifies that the search condition entered in the form be named searchCond.

<jsp:useBean id="queryBean" class="mybeans.JDBCQueryBean" scope="session" />
<jsp:setProperty name="queryBean" property="searchCond" />

<HTML>
<HEAD> <TITLE> The UseJDBCQueryBean JSP  </TITLE> </HEAD>
<BODY BGCOLOR="white">

<% String searchCondition = request.getParameter("searchCond"); 
   if (searchCondition != null) { %>
      <H3> Search results for : <I> <%= searchCondition %> </I> </H3>
      <%= queryBean.getResult() %>
      <HR><BR>
<% }  %>

<B>Enter a search condition for the EMP table:</B>

<FORM METHOD="get"> 
<INPUT TYPE="text" NAME="searchCond" VALUE="ename LIKE 'A%' " SIZE="40">
<INPUT TYPE="submit" VALUE="Ask Oracle">
</FORM>

</BODY>
</HTML>

Figure 4-2 shows sample input and output for this page:

Figure 4-2 Sample Query Results Using JDBCQueryBean

Description of Figure 4-2  follows
Description of "Figure 4-2 Sample Query Results Using JDBCQueryBean"

Advantages of HttpSessionBindingListener

In the preceding example, an alternative to the HttpSessionBindingListener mechanism would be to close the connection in a finalize() method in the JavaBean. The finalize() method would be called when the bean is garbage-collected after the session is closed. The HttpSessionBindingListener interface, however, has more predictable behavior than a finalize() method. Garbage collection frequency depends on the memory consumption pattern of the application. By contrast, the valueUnbound() method of the HttpSessionBindingListener interface is called reliably at session shutdown.

Overview of Oracle Value-Added Features for Resource Management

OC4J JSP provides the JspScopeListener interface for managing application-scope, session-scope, request-scope, or page-scope resources in a servlet 2.3 environment such as OC4J.

This mechanism adheres to servlet and JSP standards in supporting objects of page, request, session, or application scope. To create a class that supports session scope as well as other scopes, you can integrate JspScopeListener with HttpSessionBindingListener by having the class implement both interfaces. For page scope in OC4J environments, you also have the option of using an Oracle-specific runtime implementation.

For information about configuration and how to integrate with HttpSessionBindingListener, see the Oracle Application Server Containers for J2EE JSP Tag Libraries and Utilities Reference.


Important:

JspScopeListener is deprecated in the OC4J 10.1.2 implementation, and will be desupported in future implementations.

Runtime Error Processing

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.

Servlet and JSP Runtime Error Mechanisms

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

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".)

In a servlet 2.2 or higher environment, you can also specify a default error page in the web.xml deployment descriptor through instructions such as the following:

<error-page>
   <error-code>404</error-code>
   <location>/error404.html</location>
</error-page>

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

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.

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.

Code for nullpointer.jsp

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

Code for myerror.jsp

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

This example results in the output shown in Figure 4-3.

Figure 4-3 Sample Error Page

Description of Figure 4-3  follows
Description of "Figure 4-3 Sample Error Page"


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.