Oracle Application Server Containers for J2EE Support for JavaServer Pages Developer's Guide 10g (9.0.4) Part Number B10320-01 |
|
This chapter discusses basic programming considerations for JSP pages, including JSP-servlet interaction and database access, with examples provided.
The following sections are included:
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:
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" />
Important: You cannot include or forward to a servlet in JServ or other servlet 2.0 environments; you would have to write a JSP wrapper page instead. For information, see "Dynamic Includes and Forwards in JServ". |
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".
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:
ServletContext sc = this.getServletContext();
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.
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.
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:
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.
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.
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
.
<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>
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); } }
<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>
The following sections discuss OC4J JSP and Oracle features to consider when accessing data:
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 Oracle9i JDBC Developer's Guide and Reference.
The OC4J JSP container also supports EJB calls as well as SQLJ (embedded SQL in Java).
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.
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).
<%@ 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(); } %>
The graphic below illustrates sample output for the following input:
sal >= 2500 AND sal < 5000
Text description of the illustration jdbcresu.gif
JSP applications in OC4J can use features for the following performance enhancements, supported through Oracle JDBC extensions:
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.
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.
It is also possible to use the Oracle JDBC OracleConnectionCacheImpl
class directly, as though it were a JavaBean, as in the following example (although all OracleConnectionCacheImpl
functionality is available through ConnCacheBean
):
<jsp:useBean id="occi" class="oracle.jdbc.pool.OracleConnectionCacheImpl" scope="session" />
The same properties are available in OracleConnectionCacheImpl
as in ConnCacheBean
. They can be set either through jsp:setProperty
tags or directly through the class setter methods.
For information about the Oracle JDBC connection caching scheme and the OracleConnectionCacheImpl
class, see the Oracle9i JDBC Developer's Guide and Reference.
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.
Statement caching is also available directly through the Oracle JDBC OracleConnection
and OracleConnectionCacheImpl
classes. For information about the Oracle JDBC statement caching scheme and the OracleConnection
and OracleConnectionCacheImpl
classes, see the Oracle9i JDBC Developer's Guide and Reference.
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 Oracle9i JDBC Developer's Guide and Reference.
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 Oracle9i JDBC Developer's Guide and Reference.
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 Oracle9i JDBC Developer's Guide and Reference.
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:
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:
<ejb-ref>
element in the application web.xml
file for each EJB called from a JSP page.
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.
ejb-jar.xml
file in the EJB archive. Deployment requirements are very similar to the requirements for servlets.
The key steps required for a JSP page to invoke an EJB are the following:
page
directive for this.
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.
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:
taglib
directive to specify the tag prefix and the tag library descriptor (TLD) file that you will use.
useHome
tag.
createBean
tag inside an EJB useBean
tag.
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.
Important: SQLJ is being desupported after the current release. Consult MetaLink, at the following location, for the desupport notice: http://metalink.oracle.com/ |
SQLJ is a standard syntax for embedding static SQL instructions directly in Java code, greatly simplifying database-access programming. The OC4J JSP container supports the Oracle SQLJ implementation, allowing you to use SQLJ syntax in JSP statements. SQLJ statements are indicated by the #sql
token. Oracle SQLJ database access is typically through the Oracle JDBC drivers.
For general information about Oracle SQLJ programming features, syntax, and command-line options, see the Oracle9i SQLJ Developer's Guide and Reference.
Following is a sample SQLJ JSP page. The page
directive imports classes that are typically required by SQLJ.
<%@ page language="sqlj" import="sqlj.runtime.ref.DefaultContext,oracle.sqlj.runtime.Oracle" %> <HTML> <HEAD> <TITLE> The SQLJQuery JSP </TITLE> </HEAD> <BODY BGCOLOR="white"> <% String empno = request.getParameter("empno"); if (empno != null) { %> <H3> Employee # <%=empno %> Details: </H3> <%= runQuery(empno) %> <HR><BR> <% } %> <B>Enter an employee number:</B> <FORM METHOD="get"> <INPUT TYPE="text" NAME="empno" SIZE=10> <INPUT TYPE="submit" VALUE="Ask Oracle"); </FORM> </BODY> </HTML> <%! private String runQuery(String empno) throws java.sql.SQLException { DefaultContext dctx = null; String ename = null; double sal = 0.0; String hireDate = null; StringBuffer sb = new StringBuffer(); try { dctx = Oracle.getConnection("jdbc:oracle:oci8:@", "scott", "tiger"); #sql [dctx] { SELECT ename, sal, TO_CHAR(hiredate,'DD-MON-YYYY') INTO :ename, :sal, :hireDate FROM scott.emp WHERE UPPER(empno) = UPPER(:empno) }; sb.append("<BLOCKQUOTE><BIG><B><PRE>\n"); sb.append("Name : " + ename + "\n"); sb.append("Salary : " + sal + "\n"); sb.append("Date hired : " + hireDate); sb.append("</PRE></B></BIG></BLOCKQUOTE>"); } catch (java.sql.SQLException e) { sb.append("<P> SQL error: <PRE> " + e + " </PRE> </P>\n"); } finally { if (dctx!= null) dctx.close(); } return sb.toString(); } %>
This example uses the JDBC OCI driver, which requires an Oracle client installation. The Oracle
class used in getting the connection is provided with the Oracle SQLJ implementation.
Entering employee number 7788 results in output such as the following:
Text description of the illustration testsqlj.gif
You can trigger the OC4J JSP translator to invoke the Oracle SQLJ translator in one of two ways:
or:
Either of these results in the JSP translator generating a .sqlj
file instead of a .java
file. The Oracle SQLJ translator is then invoked to translate the .sqlj
file into a .java
file.
Using SQLJ results in additional output files--see "Generated Files and Locations".
Important:
|
When you execute or pretranslate a SQLJ JSP page, you can specify desired Oracle SQLJ option settings. This is true both in on-demand translation scenarios and pretranslation scenarios, as follows:
sqljcmd
configuration parameter. This parameter, in addition to allowing you to specify a particular SQLJ translator executable, enables you to set SQLJ command-line options.
For information about sqljcmd
, see "JSP Configuration Parameters".
ojspc
pretranslation tool, use the ojspc -S
option. This option enables you to set SQLJ command-line options.
For information, see "Command-Line Syntax for ojspc" and "Option Descriptions for ojspc".
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
(or xsu111.jar
for JDK 1.1.x), 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.
The following sections discuss standard features and Oracle value-added features for resource management:
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.
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.
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) {} } }
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>
Following is sample input and output for this page:
Text description of the illustration jdbcquer.gif
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.
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 or JServ 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.
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.
This section describes servlet 2.3 and JSP 1.2 mechanisms for handling runtime exceptions, including the use of JSP error pages.
Any runtime error encountered during execution of a JSP page is handled through the standard Java exception mechanism in one of two ways:
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.
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.
The following example, nullpointer.jsp
, generates an error and uses an error page, myerror.jsp
, to output contents of the implicit exception
object.
<HTML> <BODY> <%@ page errorPage="myerror.jsp" %> Null pointer is generated below: <% String s=null; s.length(); %> </BODY> </HTML>
<HTML> <BODY> <%@ page isErrorPage="true" %> Here is your error: <%= exception %> </BODY> </HTML>
This example results in the following output:
Text description of the illustration myerror.gif
|
![]() Copyright © 2000, 2003 Oracle Corporation. All Rights Reserved. |
|