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:
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:
Operate on input data that is encapsulated in a request object
Respond to a query with data encapsulated in a response object
Provide user session information persistence between interactions
Allow dynamic reloading while the server is running
Can be addressed with URLs. For examples, buttons on an application's pages often point to servlets
Can call other servlets and/or JSP pages
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 6 Administrator’s Guide.
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.
Web Server has the following web application response caching capabilities:
Caching is configurable based on the servlet name or the URI.
When caching is based on the URI, the URI can include user-specified parameters in the query string. For example, a response from /garden/catalog?category=roses is different from a response from /garden/catalog?category=lilies. These responses are stored under different keys in the cache.
Cache size, entry timeout, and other caching behaviors are configurable.
Entry timeout is measured from the time an entry is created or refreshed. You can override this timeout for an individual cache mapping by specifying the cache-mapping element timeout.
You can determine caching criteria programmatically by writing a cache helper class. For example, if a servlet only stores the time when a back-end data source was last modified, you can write a helper class to retrieve the last-modified timestamp from the data source and decide whether to cache the response based on that timestamp. See CacheHelper Interface.
You can determine cache key generation programmatically by writing a cache key generator class. See CacheKeyGenerator Interface.
All non-ASCII request parameter values specified in cache key elements must be URL encoded. The caching subsystem attempts to match the raw parameter values in the request query string.
The newly updated classes affect data what gets cached. The web container clears the cache during dynamic deployment or reloading of classes.
The following HttpServletRequest request attributes are:
com.sun.appserv.web.cachedServletName, the cached servlet target
com.sun.appserv.web.cachedURLPattern, the URL pattern being cached
If you enable caching but do not provide any special configuration for a servlet or JSP page, the default cache configuration is as follows:
The default cache timeout is 30 seconds.
Only the HTTP GET method is eligible for caching.
HTTP requests with cookies or sessions automatically disable caching.
No special consideration is given to Pragma:, Cache-control:, or Vary: headers.
The default key consists of the servlet path minus pathInfo and the query string.
A least-recently-used list is maintained to delete cache entries if the maximum cache size is exceeded.
Key generation concatenates the servlet path with key field values, if any are specified.
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; }
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.
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); }
Consider the following guidelines for improving servlet performance:
Increase the Java heap size to help garbage collection. The Java heap size can be adjusted by adjusting the values specified to the —Xms and —Xmx jvm- options in server.xml. For example, <jvm-options>-Xms128m-Xmx256m</jvm-options> sets the minimum Java heap size to 128 MB and 256 MB. For more information, see Sun Java System Web Server 7.0 Update 6 Administrator’s Guide.
For information on tuning the Garbage Collector see, Managing Memory and Garbage Collection in Sun Java System Web Server 7.0 Update 6 Performance Tuning, Sizing, and Scaling Guide.
Set the stack space if applications use deep recursion, or in any cases where very complex JSP pages are used.
You can set the stack space using set-thread-pool-prop wadm command. For example, $wadm set-thread-pool-prop [other args] stack-size=544288. For more information, see Sun Java System Web Server 7.0 Update 6 NSAPI Developer’s Guide.
Create servlet sessions only if required as the Session ID generator employs cryptographically unique random number generation algorithms. While sessions are being created, limit the size of sessions and configure them depending on whether the application uses short-lived or long-lived sessions. For more information on optimal session configuration, see Configuring the Web Application’s Session Settings in Sun Java System Web Server 7.0 Update 6 Performance Tuning, Sizing, and Scaling Guide.
Use servlet cache when possible. For more information, see Caching Servlet Results.
Use precompiled JSPs if the JSPs do not change after deployment to the Web Server. The precompiled JSPs should include the reload-interval property setting in the jsp-config element in sun-web.xml. This eliminates time-consuming compilation and periodic checking by the Web Server.
Reduce the number of directories in the classpath.
Disable dynamic reloading.
Disable the Java Security Manager.
For more information about maximizing servlet and JSP performance, see Tuning Java Web Application Performance in Sun Java System Web Server 7.0 Update 6 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 6 Performance Tuning, Sizing, and Scaling Guide.
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.
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:
The ServletRequest.setCharacterEncoding() method.
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.
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.
When processing a servlet response, the server uses the following order of precedence, first to last, to determine the response character encoding:
The ServletResponse.setContentType () method or the ServletResponse.setLocale () method.
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
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:
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 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.
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:
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:
Servlets.startup: This servlet should contain the load-on-startup element.
Servlets.config.reloadInterval: This setting translates to the dynamicreloadinterval attribute of the jvm element in servlet.xml. This instance-wide setting affects all virtual servers and all web applications.
Servlet.sessionmgr: This element translates to the session-manager element in the sun-web.xml.