Skip Headers

Oracle9iAS Migrating From WebSphere
Release 9.0.2

Part Number A95110-01
Go To Documentation Library
Home
Go To Table Of Contents
Contents
Go To Index
Index

Go to previous page Go to next page

3
Migrating Servlets

This chapter discusses key servlet features and APIs, WebSphere support for servlet APIs and its extensions to standards, and OC4J support for servlet APIs. It also includes a step-by-step migration path for servlets deployed on WebSphere to Oracle9iAS OC4J container.

Overview of the Java Servlet API

A servlet is an instance of Java class running with in a web container and servlet engine. Servlets are used for generating dynamic web pages. Servlets receive and respond to requests from web clients, usually via the HTTP protocol.

Servlets have several advantages over traditional CGI programming:

The servlet API is specified in two java extension packages: javax.servlet and javax.servlet.http. Most servlets, however, extend one of the standard implementations of that interface, namely javax.servlet.GenericServlet and javax.servlet.http.HttpServlet. Of these, the classes and interfaces in javax.servlet are protocol independent, while javax.servlet.http contain classes specific to HTTP.

The servlet API provides support in four categories:

Table 3-1 identifies the servlet API classes according to the purpose they serve.

Table 3-1 Servlet API Classes
Purpose Class or Interface

Servlet implementation

javax.servlet.Servlet

javax.servlet.SingleThreadModel

javax.servlet.GenericServlet

javax.servlet.httpServlet

Servlet configuration

javax.servlet.ServletConfig

Servlet exceptions

javax.servlet.ServletException

javax.servlet.UnavailableException

Request/response

javax.servlet.ServletRequest

javax.servlet.ServletResponse

javax.servlet.ServletInputStream

javax.servlet.ServletOutputStream

javax.servlet.http.HttpServletRequest

javax.servlet.http.HttpServletResponse

Session tracking

javax.servlet.http.HttpSession

javax.servlet.http.HttpSessionBindingListner

javax.servlet.http.HttpSessionBindingEvent

javax.servlet.http.Cookie

Servlet context

javax.servlet.ServletContext

Servlet collaboration

javax.servlet.RequestDispatcher

Servlet Lifecycle

Servlets run on the web server platform as part of the same process as the web server itself. The web server is responsible for initializing, invoking, and destroying each servlet instance. A web server communicates with a servlet through a simple interface, javax.servlet.Servlet.

This interface consists of three main methods

and two ancillary methods:

The init() Method

When a servlet is first loaded, its init() method is invoked, and begins initial processing such as opening files or establishing connections to servers. If a servlet has been permanently installed in a server, it is loaded when the server starts.

Otherwise, the server activates a servlet when it receives the first client request for the services provided by the servlet. The init() method is guaranteed to finish before any other calls are made to the servlet, such as a call to the service() method. The init() method is called only once; it is not called again unless the servlet is reloaded by the server.

The init() method takes one argument, a reference to a ServletConfig object, which provides initialization arguments for the servlet. This object has a method getServletContext() that returns a ServletContext object, which contains information about the servlet's environment.

The service() Method

The service() method is the heart of the servlet. Each request from a client results in a single call to the servlet's service() method. The service() method reads the request and produces the response from its two parameters:

There are two ways for a client to send information to a servlet. The first is to send parameter values and the second is to send information via the InputStream (or Reader). Parameter values can be embedded into a URL. The service() method's job is simple--it creates a response for each client request sent to it from the host server. However, note that there can be multiple service requests being processed simultaneously. If a service method requires any outside resources, such as files, databases, or some external data, resource access must be thread-safe.

The destroy() Method

The destroy() method is called to allow the servlet to clean up any resources (such as open files or database connections) before the servlet is unloaded. If no clean-up operations are required, this can be an empty method.

The server waits to call the destroy() method until either all service calls are complete, or a certain amount of time has passed. This means that the destroy() method can be called while some longer-running service() methods are still running. It is important that you write your destroy() method to avoid closing any necessary resources until all service() calls have completed.

Session Tracking

HTTP is a stateless protocol, which means that every time a client requests a resource, the protocol opens a separate connection to the server, and the server doesn't preserve the context from one connection to another; each transaction is a isolated. However, most web applications aren't stateless. Robust Web applications need to interact with with users and remember the user the nature of a given user's requests, making data collected about the user in one request available to the next request from the same user. A classic example would be the shopping cart application, from internet commerce. The Servlet API provides techniques for identifying a session and associating data with it, even over multiple connections. These techniques include the following:

To eliminate the need for manually managing the session information within application code (regardless of the technique used), you use the HttpSession class of the Java Servlet API. The HttpSession interface allows servlets to:

Cookies

Cookies are probably the most common approach for session tracking. Cookies store information about a session in a human-readable file on the client's machine. Subsequent sessions can access the cookie to extract information. The server associates a session ID from the cookie with the data from that session. This becomes more complicated when there are multiple cookies involved, when a decision must be made about when to expire the cookie, and when many unique session identifiers are needed. Also, a cookie has a maximum size of 4K, and no domain can have more than 20 cookies. Cookies pose some privacy concerns for users. Some people don't like the fact that a program can store and retrieve information from their local disk, and disable cookies or delete them altogether. Therefore, they are not dependable as a sole mechanism for session tracking.

URL rewriting

The URL rewriting technique works by appending data to the end of each URL that identifies a session. The server associates the identifier with data it has stored about the session. The URL is constructed using an HTTP GET, and may include a query string containing pairs of parameters and values. For example:

 http://www.server.com/getPreferences?uid=username&bgcolor=red&fgcolor=blue. 

Hidden form fields in HTML

Hidden form fields are another way to store information about the session. The hidden data can be retrieved later by using the HTTPServletRequest object. When a form is submitted, the data is included in the GET or POST. A note of caution though: form fields can be used only on dynamically generated pages,so their use is limited. And there are security holes: people can view the HTML source to see the stored data.

The HttpSession object

No matter the technique(s) used to collect session data, it must be stored somewhere. The HttpSession object can be used to store the session data from a servlet and associate it with a user.

The basic steps for using the HttpSession object are:

  1. Obtain a session object

  2. Read or write to it

  3. Terminate the session by expiring it, or allowing it to expire on its own

A session persists for a certain time period, up to forever, depending on the value set in the servlet. A unique session ID is used to track multiple requests from the same client to the server. Persistence is valid within the context of the Web application, which may encompass multiple servlets. A servlet can access an object stored by another servlet; the object is distinguished by name and is considered bound to the session. These objects (called attributes when set and get methods are performed on them) are available to other servlets within the scope of a request, a session, or an application.

Servlets are used to maintain state between requests, which is cumbersome to implement in traditional CGI and many CGI alternatives. Only a single instance of the servlet is created, and each request simply results in a new thread calling the servlet's service method (which calls doGet or doPost). So, shared data simply has to be placed in a regular instance variable (field) of the servlet. Thus,the servlet can access the appropriate ongoing calculation when the browser reloads the page and can keep a list of the N most recently requested results, returning them immediately if a new request specifies the same parameters as a recent one. Of course, the normal rules that require authors to synchronize multithreaded access to shared data still apply to servlets.

Servlets can also store persistent data in the ServletContext object, available through the getServletContext method. ServletContext has setAttribute and getAttribute methods that enable storage of arbitrary data associated with specified keys. The difference between storing data in instance variables and storing it in the ServletContext is that the ServletContext is shared by all servlets in the servlet engine or in the Web application.

J2EE Web Applications

A Web application, as defined in the servlet specification, is a collection of servlets, JavaServer Pages (JSPs), Java utility classes and libraries, static documents such as HTML pages, images , client side applets, beans, and classes, and other Web resources that are set up in such a way as to be portably deployed across any servlet-enabled Web server. A Web applications, can be contained in entirety within a single archive file and deployed by placing the file into a specific directory.

Web Application Archive (WAR)

Web application archive files have the extension .war. WAR files are .jar files (created using the jar utility) saved with an alternate extension. The JAR format allows JAR files to be stored in compressed form and have their contents digitally signed. The .war file extension was chosen over .jar to distinguish them for certain operations. An example of a WAR file listing is shown below:

index.html 
howto.jsp 
feedback.jsp 
images/banner.gif 
images/jumping.gif 
WEB-INF/web.xml 
WEB-INF/lib/jspbean.jar 
WEB-INF/classes/MyServlet.class 
WEB-INF/classes/com/mycorp/frontend/CorpServlet.class 
WEB-INF/classes/com/mycorp/frontend/SupportClass.class 

On install, a WAR file can be mapped to any URI prefix path on the server. The WAR file then handles all requests beginning with that prefix. For example, if the WAR file above were installed under the prefix /demo, the server would use it to handle all requests beginning with /demo. A request for /demo/index.html would serve the index.html file from the WAR file. A request for /demo/howto.jsp or /demo/images/banner.gif would also serve content from the WAR file.

About the WEB-INF directory

The WEB-INF directory is special. The files in it are not served directly to the client; instead, they contain Java classes and configuration information for the Web application. The directory behaves like a JAR file's META-INF directory; it contains metainformation about the archive contents. The WEB-INF/classes directory contains the class files for the Web application's servlets and supporting classes. WEB-INF/lib contains classes stored in JAR files. For convenience, web server class loaders automatically look to WEB-INF/classes and WEB-INF/lib for their classes--no extra install steps are necessary.

The servlets under WEB-INF in the example Web application listing can be invoked using URIs like /demo/servlet/MyServlet and /demo/servlet/com.mycorp.frontend.CorpServlet.

Note that every request for this application begins with /demo, even requests for servlets.

The web.xml file in the WEB-INF directory defines descriptors for a Web Application. This file contains configuration information about the Web application in which it resides and is used to register your servlets, define servlet initialization parameters, register JSP tag libraries, define security constraints, and other Web Application parameters .

Differences between Servlet 2.0, 2.1 and 2.2

The Servlet API in the J2EE specification is continously evolving. In a span of two years Servlet API 2.0 , 2.1, 2.2 has been published; the most recent version as of this writing is Servlet API 2.3. The fundamental architecture of servlets has not changed much, so most of the API is still relevant. However, there are enhancements and some new functionality, and some APIs have been deprecated.

This section will cover the major difference between Servlet API 2.0 , 2.1 ,2.2 and 2.3 draft specification.

Highlights of the Java Servlet API 2.1

The Servlet 2.1 API highlights include:

New Features in the Java Servlet API 2.2

The Servlet API 2.2 specification changed the term 'servlet engine', replacing it with 'servlet container'. This change is indicative of the Java Servlet API is now a required API of the Java 2 Platform, Enterprise Edition (J2EE) specification and, throughout J2EE's terminology, container is preferred over engine. Servlet API 2.2 introduced the following new features:

Servlet API 2.3

The Servlet API 2.3 leaves the core of servlets relatively untouched. Additions and changes include:

Filters and Servlet Chaining

Filtering support is provided as a part of the Servlet 2.3 API. WebSphere Advanced Edition 3.5.3 achieves similar filtering functionality with a WebSphere-specific package. Oracle9iAS Containers for J2EE (OC4J) supports the Java servlet 2.3 filtering specification.

Filtering is a method of loading and invoking servlets in a web server. Both local and remote servlets can be part of a servlet chain (defined below). There are restrictions, however, on chaining the local internal servlets, and these restrictions are specific to the J2EE container used. For example, in WebSphere, if an internal servlet is used in a chain, it must be the first servlet in the chain. Internal servlets include: file servlet, pageCompile servlet, ssInclude servlet, and template servlet.

Servlet Chains

For some requests, a chain of ordered servlets can be invoked rather than just one servlet. The input from the browser is sent to the first servlet in the chain and the output from the last servlet in the chain is the response sent back to the browser. Each servlet in the chain receives inputs from, and transmits outputs to, the servlet before and after it, respectively. A chain of servlets can be triggered for an incoming request by using:

WebSphere Servlet API Support

WebSphere version 3.5.2 and version 3.5.3 maintain compatibility with existing applications while simultaneously supporting the Java Servlet API 2.2 specification. But this support is partial, and you can choose only one. To ensure compatibility, a new option was added to servlet container properties in the Administrative console. This new option, the Select Servlet Engine Mode, is located on the Servlet Engine Properties view. The Select Servlet Engine Mode option toggles between the following two different 'runtime' modes:

WebSphere Advanced Edition 3.5.3 Compatibility Mode

This mode maintains behavior with existing WebSphere Application Server v3.5 and v3.5.1 applications at the expense of full compliance with the Java Servlet API 2.2 specification. In compatibility mode, the servlet engine is Servlet 2.2 specification level compliant, except for the method and behavior changes noted below. This capability is provided to allow existing WebSphere Advanced Edition v3.5 and v3.5.1 applications to successfully execute until they are migrated to fully compliant Servlet 2.2 level applications.

Full Servlet 2.2 Compliance Mode

This mode maintains compliance with the Java Servlet API 2.2 specification at the expense of compatibility with existing WebSphere Application Server v3.5 and v3.5.1 applications.

The default mode is the Compatibility Mode. You select the desired mode using the Administrative Console, Servlet Engine General tab.

Servlet API 2.2 support

WebSphere Advanced Edition 3.5.3 has partial support for the Servlet 2.2 API. The supported API features are:

The following Servlet 2.2 API features are not supported:

WebSphere Extensions to the Servlet API

The WebSphere Application Server includes its own packages that extends and adds to the Java Servlet API. The extensions and additions are provided to manage session state, create personalized Web pages, generate better servlet error reports, and access databases.

The Application Server API packages and classes are:

Oracle9iAS Servlet API Suport

Oracle9iAS OC4J is a fully compliant implementation of the Java Servlets 2.2 and 2.3 specifications. As such, standard Java Servlets 2.2 code will work correctly. WebSphere Advanced Edition, on the other hand, has partial support for the Java Servlets 2.2 specification as described above. In particular, the security support remains at the Servlet 2.1 level, and there is no support for J2EE references that would normally be defined in the web.xml file associated with the Web application. There is also no direct support for J2EE Web Abpplications.

Because of these differences in API support and WebSphere extensions, an application may require code level changes before it can be migrated if it uses extensions or deprecated method calls. Since WebSphere does not support J2EE deployment descriptors, existing applications must be packaged into the J2EE Web Application structure before deployment on Oracle9iAS OC4J.

Migrating Standalone Servlets to OC4J

We migrated example servlets provided with WebSphere Advanced Edition 3.5.3. Some of these examples were not migrated because they used WebSphere-specific extensions. For example, we did not migrate AbstractLoginServlet because it uses a single sign-on package specific to WebSphere.

We migrated these servlets (located in in WebSphereInstallHome/Servlets):

In addition to these, we migrated packaged Web Applications that use WebSphere- specific deployment descriptors.

These examples were migrated without code changes. All that was required was to place these servlets in
<ORACLE_HOME>/j2ee/home/default-web-app/WEB-INF/classes. The OC4J servlet container loads these servlets automatically. You can invoke these servlets from a browser using http://hostname:portnumber/servlet/HelloWorldServlet.

WebSphere provides another way of deploying standalone servlets (that is, servlets that require initialization parameters and configuration information). These servlets are deployed in WebSphere using a deployment descriptor whose name is the name of the servlet and ends with .servlet. This WebSphere-specific deployment descriptor must be migrated to the J2EE Web application deployment descriptor before it can be deployed in OC4J.

Example 3-1 SnoopServlet.servlet Deployment Descriptor

<servlet>
  <name>snoop</name>
  <description>snoop servlet</description>
  <code>SnoopServlet</code>
  <servlet-path>/servlet/snoop/*</servlet-path>
  <servlet-path>/servlet/snoop2/*</servlet-path>
  <init-parameter>
    <name>param1</name>
    <value>test-value1</value>
  </init-parameter>
  <autostart>false</autostart>
</servlet>

Sample .servlet file: SnoopServlet.servlet

The Snoop Servlet can be migrated by placing Servlet in
<ORACLE_HOME>/j2ee/home/default-web-app/WEB-INF/classes and editing web.xml located in
<ORACLE_HOME>/j2ee/home/default-web-app/WEB-INF.

Example 3-2 Migrated SnoopServlet Deployment Descriptor

<web-app>
  <servlet>
    <servlet-name>snoop</servlet-name>
    <description>snoop servlet</description>
    <servlet-class>SnoopServlet</servlet-class>
    <servlet-path>/servlet/snoop/*</servlet-path>
    <servlet-path>/servlet/snoop2/*?/servlet-path?
    <init-param>
      <param-name>param1</param-name>
      <param-value>test-value1</param-value>
    </init-param> 
    <autostart>false</autostart>
  </servlet>
</web-app>

Migrating Cluster-aware applications to OC4J

Clustering and load balancing are two key features of an enterprise application server. These features make the application server available, fault tolerant, and scalable. The load balancer replicates state of an individual node to the cluster of instances so that if a node fails, the state information is preserved elsewhere. The cluster configuration provided by OC4J accomplishes the following:

WebSphere and Oracle9iAS OC4J both provide clustering and load balancing session failover. Oracle9iAS OC4J also supports HTTP tunneling of RMI requests and responses without clustering. If you have a cluster-aware application running on WebSphere, it can be migrated to an OC4J instance (a set of OC4J processes, equivalent to a cluster).

islandThe OC4J configuration incorporates the concept of islands. An island is a set of OC4J processes that have uniform application configuration and replicated application state. An island is a subset of processes within an OC4J instance.

Configuring an OC4J Island (in OC4J standalone mode)


Note:

The instructions in this section show you how to configure a island manually. This can be done in a development environment where OC4J is running in standalone mode. If you are configuring an island in an Oracle9iAS cluster, use the Oracle Enterprise Manager web pages or the dcmctl command line utility. Information on using these can be found in Oracle9i Application Server Administrator's Guide and Oracle9iAS Containers for J2EE User's Guide


The following steps explain how to configure an OC4J island:

  1. Install your web application on all of the nodes in your cluster.

    1. First, make sure that the nodes you are using in your cluster have the same web application installed. If you do not want to install the application in two places, you can place it on a shared drive that both servers access.

    2. Start all your nodes and check that the web-applications are working correctly on all of them.

  2. Set up your web-application to replicate its state to the cluster.

    1. Edit the orion-web.xml deployment descriptor for the web application, located at:

      <ORACLE_HOME>/j2ee/home/application-deployments/
      application-name/web-app-name/

    2. If you want to add clustering for all web applications in the site, edit the orion-web.xml of the global web application located at

      <ORACLE_HOME>/j2ee/home/config/
      global-web-application.xml

      Add the following to the main body of the <orion-web-app> tag:

      <cluster-config/>
      
      
  3. Optional: Specify the multicast host and IP address on which to transmit and receive cluster data.

  4. Optional: Specify the port on which to transmit and receive cluster data.

  5. Specify the ID (number) of the node to identify itself within the cluster. The default is localhost.

  6. Optional: Repeat steps 4, 5 and 6 for all the nodes in your cluster.

    The HTTPSession data will now be replicated (as long as it is serializable, or an EJB reference). Note, however, that if the EJBs are located on a server that goes down, the references might become invalid. The ServletContext data is also replicated.


    Note:

    t is important to understand that load balancing, in this case, is implemented for the web-component, not the EJB (EJBs have a different way of load balancing using client stubs). When using multiple islands, you may want to use different multicast IP addresses, to enable smart routing of multicast packets in your network, and just send traffic on certain IP addresses to certain servers.


  7. Configure your islands.

    Islands are connected to a certain site rather than to a web-application. To configure an island:

    1. Edit the web-site.xml file for the website your web application is deployed on (for example, default-web-site.xml if you are clustering the default web-site). Add the following to the <web-site> tag:

      cluster-island="1"
      
      

      If your cluster has more than one island, you will specify different island values for the servers that belong to different islands. State is shared only within an island.

    2. Specify the host the web-site is serving using the host="<hostname/ip address>" attribute in the <web-site> tag.

  8. Tell the servers about the load balancer. In the same file, the web-site.xml for your web site, you also specify where the load balancer for the site is located.

    1. In the main body of the <website> tag, add:

      <frontend host="balancer hostname" port="balancer port" />
      
      

      where balancer hostname and balancer port are the hostname and port of the server that will be running the load balancer.

  9. In the /WEB-INF/web.xml of your application put in the tag

    </distributable>
    
    

    This tag indicates that the application is distributable (a feature of the J2EE 1.2 specification).

  10. Access the load balancer's host and port with a browser. You will notice how the request is sent to a server. If you request the same page again from the same client, your request will probably be sent to the same server again, but if you request the same page from different clients, you will see that the client requests get balanced.

    To test the state replication, you can try accessing

    <ORACLE_HOME>/j2ee/home/servlet/SessionServlet

    Make the request a single time, and check which server becomes the primary server for the session. Stop that server and make the request again. The desired result is that the request is part of the same session as before but on a different node. And, the counter is updated correctly.

How OC4J Island Works (in OC4J standalone mode)

For all of the islands, there is a single load balancer OC4J instance that dispatches requests to the application clones.


Go to previous page Go to next page
Oracle
Copyright © 2002 Oracle Corporation.

All Rights Reserved.
Go To Documentation Library
Home
Go To Table Of Contents
Contents
Go To Index
Index