Skip Headers

Oracle® Application Server Containers for J2EE Support for JavaServer Pages Developer's Guide 10g Release 3 (10.1.3) Part No. B14430-01 |
| Home | Solution Area | Contents | Index

Previous | 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:

- Before You Start

- General JSP Programming Strategies

- JSP Best Practices

- Working with Servlets

- Processing Runtime Errors

## 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:

- Understanding Application Root Functionality

- Understanding OC4J Classpath Functionality

- Packages Imported By Default in OC4J

- Following JSP File Naming Conventions

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

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

No te 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 Pa ckages 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:

  - "Summary of JSP Configuration Parameters"

  - "Complete Summary of ojspc Command Line Options"

### 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:

- Using JavaBeans Versus Scriptlets

- Using Static Includes Versus Dynamic Includes

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 JavaB eans 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 Incl udes 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 res ource 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 V ariable 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 D irectives

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 Na ming 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 Reaso ns 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 Pa ges 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 Ser vlets

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:

- Invoking a Servlet from a JSP Page

- Passing Data to a Servlet Invoked from a JSP Page

- Invoking a JSP Page from a Servlet

- Passing Data Between a JSP Page and a Servlet

- JSP-Servlet Interaction Samples

### 6.4.1 Invoki ng 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 Passi ng 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 Invoki ng 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 Passin g 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-Se rvlet 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 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.