Sun Java System Web Server 7.0 Update 4 Developer's Guide to Java Web Applications

Chapter 4 Developing Servlets

This chapter describes how to create servlets to control web application interactions running on a Web Server. In addition, this chapter describes the Web Server features used to augment the Java Servlet 2.5 standards.

This chapter has the following sections:

About Servlets

Servlets, like applets, are reusable Java applications. Servlets, however, run on a web server rather than in a web browser.

Servlets provide a component-based, platform-independent method for building web-based applications without the performance overheads, process limitations, and platform-specific liabilities of CGI programs.

Servlets supported by the Web Server are based on the Java Servlet 2.5 specification. Servlets are created compiled and packed into a Java web application archive WAR file and then deployed to the Web Server and managed at runtime by the servlet engine

Basic characteristics of servlets include the following:

Servlet Output

By default, the System.out and System.err output of servlets is sent to the server log. During startup, server log messages are echoed to the System.err output. On Windows, no console is created for the System.err output.

You can change these defaults using the Admin Console. For more information, see Setting Up Logging for Your Server in Sun Java System Web Server 7.0 Update 4 Administrator’s Guide.

Caching Servlet Results

Web Server can cache the results of invoking a servlet, a JSP page, or any URL pattern to make subsequent invocations of the same servlet, JSP page, or URL pattern faster. The Web Server caches the request results for a specific amount of time. In this way, if another data call occurs, the Web Server can return the cached data instead of performing the operation again. For example, if your servlet returns a stock quote that updates every 5 minutes, you set the cache to expire after 300 seconds.

If caching is enabled, Web Server can cache the results produced by the servlet javax.servlet.RequestDispatcher.include() or javax.servlet.RequestDispatcher.forward(). In Sun ONE releases, the result generated by a resource for which caching was enabled was never cached if that resource was the target of a javax.servlet.RequestDispatcher.include() or javax.servlet.RequestDispatcher.forward(). This result cached only if the resource was the target of the initial request.

<sun-web-app>
<cache enable="true">
		<cache-mapping>
				<servlet-name>TestServlet</servlet-name>
				<dispatcher>REQUEST</dispatcher>
				<dispatcher>FORWARD</dispatcher>
		</cahce-mapping>
		</cache>
	  </sun-web-app>

Whether to cache results and how to cache them depends on the data involved. For example, you do not need to cache the results of a quiz submission because the input to the servlet is different each time. However, you could cache a high-level report showing demographic data taken from quiz results that is updated once an hour.

You can define how a Web Server web application handles response caching by editing specific fields in the sun-web.xml file. In this way, you can create programmatically standard servlets that still take advantage of this feature.

For more information about JSP caching, see JSP Cache Tags.

Features of Caching

Web Server has the following web application response caching capabilities:

Default Cache Configuration

If you enable caching but do not provide any special configuration for a servlet or JSP page, the default cache configuration is as follows:

CacheHelper Interface

The CacheHelper interface includes the following information:

package com.sun.appserv.web.cache;
import java.util.Map
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
/** CacheHelper interface is an user-extensible interface to customize:
 * a) the key generation b) whether to cache the response.
 */
public interface CacheHelper {
// name of request attributes
   public static final String ATTR_CACHE_MAPPED_SERVLET_NAME =
                           "com.sun.appserv.web.cachedServletName";
   public static final String ATTR_CACHE_MAPPED_URL_PATTERN =
                           "com.sun.appserv.web.cachedURLPattern";
public static final int TIMEOUT_VALUE_NOT_SET = -2;
/** initialize the helper
    * @param context the web application context this helper belongs to
    * @exception Exception if a startup error occurs
    */
   public void init(ServletContext context, Map props) throws Exception;
/** getCacheKey: generate the key to be used to cache this request
    * @param request incoming <code>HttpServletRequest</code> object
    * @returns the generated key for this requested cacheable resource.
    */
   public String getCacheKey(HttpServletRequest request);
/** isCacheable: is the response to given request cacheable?
    * @param request incoming <code>HttpServletRequest</code> object
    * @returns <code>true</code> if the response could be cached. or
    * <code>false</code> if the results of this request must not be cached.
    */
   public boolean isCacheable(HttpServletRequest request);
/** isRefreshNeeded: is the response to given request to be refreshed?
    * @param request incoming <code>HttpServletRequest</code> object
    * @returns <code>true</code> if the response needs to be refreshed.
    * or return <code>false</code> if the results of this request
    * dont need to be refreshed.
    */
   public boolean isRefreshNeeded(HttpServletRequest request);
/** get timeout for the cached response.
    * @param request incoming <code>HttpServletRequest</code> object
    * @returns the timeout in seconds for the cached response; a return
    * value of -1 means the response never expires and a value of -2 indicates
    * helper cannot determine the timeout (container assigns default timeout)
   */
public int getTimeout(HttpServletRequest request);
/**
    * Stop the helper from active use
    * @exception Exception if an error occurs
    */
   public void destroy() throws Exception;
}

Caching Example

The following example cache element in the sun-web.xml file:

<cache max-capacity="8192" timeout="60">
   <cache-helper name="myHelper" class-name="MyCacheHelper"/>
   <cache-mapping>
      <servlet-name>myservlet</servlet name>
      <timeout name="timefield">120</timeout>
      <http-method>GET</http-method>
      <http-method>POST</http-method>
   </cache-mapping>
   <cache-mapping>
      <url-pattern> /catalog/* </url-pattern>
      <!-- cache the best selling category; cache the responses to
        -- this resource only when the given parameters exist. Cache
        -- only when the catalog parameter has qliliesq or qrosesq
        -- but no other catalog varieties:
        -- /orchard/catalogbest&category=lilies
        -- /orchard/catalogbest&category=roses
        -- but not the result of
        -- /orchard/catalog?best&category=wild
      -->
      <constraint-field name=best scope=request.parameter/>
      <constraint-field name=category scope=request.parameter>
        <value> roses </value>
        <value> lilies </value>
      </constraint-field>
      <!-- Specify that a particular field is of given range but the
        -- field does not need to be present in all the requests -->
      <constraint-field name=SKUnum scope=request.parameter>
        <value match-expr=qin-range> 1000 - 2000 </value>
      </constraint-field>
      <!-- cache when the category matches with any value other than
        -- a specific value -->
      <constraint-field name="category" scope="request.parameter>
        <value match-expr="equals" cache-on-match-failure="true">bogus</value>
      </constraint-field>
   </cache-mapping>
   <cache-mapping>
      <servlet-name> InfoServlet </servlet name>
      <cache-helper-ref>myHelper</cache-helper-ref>
   </cache-mapping>
</cache>

For more information about the sun-web.xml caching settings, see Caching Elements.

CacheKeyGenerator Interface

The built-in default CacheHelper implementation enables web applications to customize the key generation. An application component in a servlet or JSP can set up a custom CacheKeyGenerator implementation as an attribute in the ServletContext.

The name of the context attribute is configurable as the value of the cacheKeyGeneratorAttrName property in the default-helper element of the sun-web.xml deployment descriptor. For more information, see default-helper.

The CacheKeyGenerator interface contains the following information:

package com.sun.appserv.web.cache;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
/** CacheKeyGenerator: a helper interface to generate the key that
 * is used to cache this request.
 *
 * Name of the ServletContext attribute implementing the
 * CacheKeyGenerator is configurable via a property of the
 * default-helper in sun-web.xml:
 * <default-helper>
 * <property
 * name="cacheKeyGeneratorAttrName"
 * value="com.acme.web.MyCacheKeyGenerator" />
 * </default-helper>
 *
 * Caching engine looks up the specified attribute in the servlet
 * context; the result of the lookup must be an implementation of the
 * CacheKeyGenerator interface.
 */
public interface CacheKeyGenerator {
/** getCacheKey: generate the key to be used to cache the
    * response.
    * @param context the web application context
    * @param request incoming <code>HttpServletRequest</code>
    * @returns key string used to access the cache entry.
    * if the return value is null, a default key is used.
    */
   public String getCacheKey(ServletContext context,
                           HttpServletRequest request);
}

Maximizing Servlet Performance

Consider the following guidelines for improving servlet performance:

For more information about maximizing servlet and JSP performance, see Tuning Java Web Application Performance in Sun Java System Web Server 7.0 Update 4 Performance Tuning, Sizing, and Scaling Guide.

For more information about container setting to maximize performance, see Tuning Web Container Within Web Server 7.0 in Sun Java System Web Server 7.0 Update 4 Performance Tuning, Sizing, and Scaling Guide.

Servlet Internationalization Issues

This section describes how Web Server determines the character encoding for the servlet request and the servlet response. For information about encodings, see http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html.

Servlet Request

When processing the servlet request, the server uses the following order of precedence, first to last, to determine the character encoding for the request parameters:

  1. The ServletRequest.setCharacterEncoding() method.

  2. A hidden field in the form, if specified using the form-hint-field attribute of the parameter-encoding element in the sun-web.xml file. For more information about this element, see parameter-encoding Element.

  3. The character encoding specified in the default-charset attribute of the parameter-encoding element in the sun-web.xml file. For more information about this element, see parameter-encoding Element.

Servlet Response

When processing a servlet response, the server uses the following order of precedence, first to last, to determine the response character encoding:

  1. The ServletResponse.setContentType () method or the ServletResponse.setLocale () method.

  2. The default encoding, which is ISO-8859–1.

To specify the character encoding that should be set in the Content-type header of the response if the response locale is set using the ServletResponse.setLocale method, use the locale-charset-map under the locale-charset-info element in the sun-web.xml file. For more information about this element, see locale-charset-info Element

Migrating Legacy Servlets

Netscape Enterprise Server/ iPlanet Web Server versions 4.0 and 4.1 supported the Java Servlet 2.1 specification. This specification did not include web applications. A deployment scheme was developed to make servlet deployment simpler. With the advent of Java web applications (WAR files) and their deployment descriptors, maintaining a proprietary deployment system is no longer necessary.

iPlanet Web Server 6.0 supported both types of deployment schemes, but the 4.x implementation (referred to as legacy servlets) was marked as deprecated (See Chapter 8 Legacy Servlet and JSP Configuration of the iPlanet Web Server, Enterprise Edition Programmer's Guide to Servlets).

Web Server versions 6.1 and 7.0 no longer support legacy servlets. The legacy properties files for the server you want to migrate (servlet.properties, context.properties, and rules.properties) are removed during migration.

Because no one-to-one mapping is possible for all of the features, legacy servlets cannot be migrated automatically. This section describes the main features involved in migrating legacy servlets to web applications.

This section includes the following topics:

JSP file by Extension

In Web Server, JSP file by extension works as it did in previous releases. Any file name in the document tree with a suffix of .jsp is treated as a JSP environment as long as the Java is turned on for the virtual server.

Servlet by Extension of Servlet by Directory

Servlet extension is not supported in Web Server. You can deploy a web application to respond to a directory, but all of the servlets must be in the WEB-INF/classes directory of the web application. You can no longer copy a servlet in the .class file into the document tree and have it run as a servlet or have all of the contents of a directory run as a servlet. The web application treats only .class files as servlets.

Registering Servlets

The legacy servlet system used a two-step process of registering servlets (servlet.properties) and mapping them to a URL (rules.properties). In Web Server, the servlets must be moved into a web application. These settings will be maintained in the web.xml file of that web application.

A registered servlet has entries in both the servlet.properties and rules.properties files.

The following example uses a servlet file called BuyNow1A.class, which responds to /buynow. It is assumed that the web application is deployed at '/'

The servlet.properties file containing:


Example 4–1 Registering Servlets Example

servlet.BuyNowServlet.classpath=D:/Netscape/server4/docs/
servlet/buy;D:/Netscape/server4/docs/myclasses
servlet.BuyNowServlet.code=BuyNow1A
servlet.BuyNowServlet.initArgs=arg1=45,arg2=online,arg3="quick shopping"

The rules.properties file has:

/buynow=BuyNowServlet

These settings must be translated to a web.xml setting. The servlet.properties setting translates into the servlet element.

The classpath is automated so no classpath setting is necessary. All classes to be used must be in the WEB-INF/classes directory or in a .jar file in the WEB-INF/lib directory of the web application.

The servlet-name element appears between the dots in the servlets.properties file. The code translates to the servlet-class, IntArgs translate to init-params. This entry will translate to the following entry:

<servlet>
<servlet-name> BuyNowServlet </servlet-name>
<servlet-class> BuyNow1A </servlet-class>
		<init-param>
				<param-value> arg1 </param-name>
				<param-value> 45 </pram-value>
		 </init-param>
		 <init-param>
				<param-name> arg2 </param-name>
				<param-value> online </param-value>
		 </init-param>
		 <init-param>
				<param-name> arg3 </param-name>
				<param-value> 'quick shopping" </param-value>
			</init-param>
</servlet>

The rules.properties entries translate to servlet-mapping elements. This entry translates to the following entry:

<servlet-mapping>
	<servlet-name> BuyNowServlet </servlet-name>
	<url-pattern> /buynow </url-pattern>
	</servlet-mapping>

Some other entries in the servlet.properties file map to the web.xml file. This includes the following information: