Oracle9i Servlet Engine Developer's Guide Release 1 (9.0.1) Part Number A90213-02 |
|
This chapter covers the following topics:
This chapter discusses the basic functionality and mode of operation of the Oracle Servlet Engine (OSE). You can find specific information about configuring the servlet engine and Web applications in Chapter 3, "OSE Configuration and Examples", in Chapter 5, "Configuring mod_ose", and in Chapter 8, "Oracle WAR Deployment".
If you need help in creating, deploying, and accessing your first servlet under the OSE/OJVM, and are not interested right now in how the OSE/OJVM operates, you can get started very quickly by having a look at the Summary.
To understand how the OSE works, it is useful to have an overall grasp of its basic building blocks and tools. These are described very briefly in this section. More detailed explanations are given in later sections of this chapter.
The OSE/OJVM runs in a virtual JVM inside an Oracle database server session. It is important to understand the OSE/OJVM session model in order to develop and tune your servlet- or JSP-based application for maximum scalability and performance.
Objects that support both Web applications and the OSE system itself are organized in a hierarchical namespace, similar conceptually to a UNIX file system, or the directories on a Windows NT disk drive. The OSE namespace is implemented using the Java Naming and Directory Interface (JNDI), and OSE/OJVM objects in the namespace are persisted in Oracle server tables.
The tool used to administer the OSE/OJVM is the session shell. The session shell is a client-side tool that connects to an Oracle server on which the Oracle JVM has been installed, and the session shell is then used to run administrative commands on the server. The session shell behaves like a UNIX shell, with built-in commands to delete objects, bind new objects, navigate the JNDI namespace, and perform administrative tasks such as creating new Web services, Web domains, and servlet contexts.
In order for a Web browser (or any other HTTP client) to connect to the OSE and access servlets or JSPs, a Web service must be established in the OJVM. The Web service uses the Oracle server HTTP presentation capability. Endpoints for client connection to the service are also established. (An endpoint is simply a port number--programmatically a TCP socket.)
A Web browser can connect to a service by sending a request URL that specifies a hostname and an endpoint. For example the URL
http://Oratest:8080/
specifies a connection to the host system Oratest
, at endpoint 8080
. The network DNS servers look up the host name, and substitute the correct 32-bit IP address in its place. If this endpoint is an OSE service, this URL would cause the default servlet for the domain to be activated. If the endpoint is omitted, then the default endpoint for the HTTP presentation on that host is used.
An OSE Web service can support one or more Web domains. While a single Web domain per service is the most common case, the OSE can also support multiple IP-based and/or name-based virtual-hosted Web domains for a single service.
A servlet context is the basic unit of organization of a Web application. Each Web domain can support one or more servlet contexts. You publish a single application's servlets, JavaServer Pages, and other objects into the servlet context.
For the OSE you can use a Web application archive (WAR) file to configure a servlet context, or you can do the configuration using session shell commands.
When a request from an HTTP client arrives at an HTTP service endpoint, an Oracle server session is started, the JVM is activated, and then OSE/OJVM is activated to handle the request.
By default, the database session is authenticated as the owner of the Web domain used to connect to the server.
HTTP clients can combine several HTTP session objects in a single database session. An HTTP session can exist for each servlet context. A servlet inside a particular context can integrate the corresponding HTTP session when calling the getSession(true)
method. If the client activates servlets from two different servlet contexts and each servlet calls getSession(true)
, then two different HTTP session instances exist in the database session. The first time an HTTP client connects to an instance of Oracle9i running OSE, a session is created inside the database. The session is a regular database session that runs its own virtual JVM.
A stateful session is useful in applications where a dialogue should exist between the client and the servlet. A cookie is sent to the client to maintain the session, that is to assure that the client can return to the same session on subsequent HTTP requests. If the client does not support cookies, the OSE uses URL rewriting to maintain session information.
The OSE supports the complete servlet interface, as required by the Servlet 2.2 specification. Any servlet that is written to operate under the OSE should be portable to another J2EE-compliant servlet container, and servlets written for other platforms will run in the OSE with no modification.
Although functionally the same as servlet activation in a non-server JVM, the servlet activation model for the OSE/OJVM depends upon the properties of the OJVM, and hence requires a different development model for optimum speed and scalability.
The Java process, and hence the Java servlet, are started up only when a request comes into the OSE service. This is the way the OJVM itself works, as described in the Oracle9i Java Developer's Guide. For this reason, heavy weight" servlets, that do a lot of initialization work when started up usually do not offer any performance advantage in the OSE/OJVM, and always incur a performance penalty on session start-up.
The OSE/OJVM supports both stateful and stateless servlets. However, if your application makes heavy use of stateless servlets, you need to be aware that each request to a stateless servlet could require a new instantiation of the OJVM, which would costly.
So if your application uses stateless servlets you should always connect to the OSE by way of Apache and mod_ose
, as mod_ose
keeps a stateless connection to the OSE open for the duration of each Apache (httpd
) process. If the application servlets do a lot of initialization (such as caching connection pools, precomputed data, or data obtained from the database), it is likely that other client requests will get hits on the cached data when Apache/mod_ose
are used. If you connect directly to the OSE/OJVM to run stateless servlets, each new HTTP request starts a new server session, and any caching that the servlet does is completely wasted.
Oracle does not recommend that you write or deploy servlets that use the Java multi threaded model in the OSE/OJVM. The OSE/OJVM works using the Oracle shared server configuration (called the Multi-Threaded Server, or MTS, configuration in Oracle8i). The shared server configuration is in itself a distributed system, and scales by adding new servers as the incoming requests multiply. So in effect the threading is being done at the server level, and each servlet executes in its own virtual JVM.
So, each thread of a multithreaded servlet cannot cache static information that is available to other threads. One JVM, one thread of control.
The following statement from the Oracle9i Java Developer's Guide (page 1-13) summarizes the special way that the OJVM operates:
"As a database server, Oracle9i efficiently schedules work for thousands of users. The Oracle9i Aurora JVM uses the facilities of the RDBMS server to concurrently schedule Java execution for thousands of users. Although Oracle9i supports Java language level threads required by the Java language specification (JLS) and Java Compatibility Kit (JCK), using threads within the scope of the database will not increase your scalability. Using the embedded scalability of the database eliminates the need for writing multi threaded Java servers. You should use the database's facilities for scheduling users by writing single-threaded Java applications. The database will take care of the scheduling between each application; thus, you achieve scalability without having to manage threads. You can still write multi threaded Java applications, but multiple Java threads will not increase your server's performance."
When a Web application is deployed in an Oracle server, the Java classes that implement the servlets and JSPs are stored in the database as SQL objects. You use the loadjava command to load a Java class to an Oracle9i database--it is stored in a SQL table in the database. The OJVM is able to resolve and execute the servlet within the OJVM context, in a way analogous to the activation of a Java Stored Procedure or an Enterprise JavaBean.
The OSE/OJVM uses JNDI to implement the namespace. The JNDI layer insulates the OSE from direct dependence on the database, but enables the database to be used for persistence of the container objects. The JNDI interface leverages the features of the Oracle9i server, including concurrency and transactional capability, as well as scalability, replication, and other advanced capabilities.
For those unfamiliar with JNDI, this section provides a very brief overview. For more information, point your Web browser to
http://java.sun.com/products/jndi/index.html
The JNDI is a set of APIs developed by Sun Microsystems as a standardized way of naming objects, and navigating to them. The OSE uses JNDI as the method of implementation for its namespace.
A namespace is simply a collection of names in a naming system. For example, UNIX provides a set of names for files stored on a file system that is organized in as a hierarchical tree structure. The OSE has a namespace that consists of objects, such as servlets, configuration objects, JSPs, as well as other material, such as graphic or sound images, that make up Web applications.
The JNDI has two fundamental concepts: contexts and references, and one fundamental action: binding. There are of course other actions, implemented by classes in the API, that allow the developer using JNDI to navigate the namespace, create new contexts, and do other operations.
When you develop a Web application for the OSE/OJVM, you use JNDI-based tools, implemented as session shell commands, to perform most administrative operations. A servlet developed for the OSE/OJVM can use the JNDI API to perform application tasks, such as calling EJBs or other J2EE components.
Since the JNDI namespace for the OSE/OJVM is persisted in SQL tables, you could use the JNDI API to store information in the OSE JNDI namespace that needs to be shared among Oracle sessions.
A reference is a name-to-object binding that points to (or names) an object that implements some functionality, for example a servlet class. A context is an object that can contain references or other contexts. That is, a context is a set of name-to-object bindings. A context is like a directory in a file system. For example, in the UNIX naming system a file path such as /usr/bin/wc
names three directories: '/' (root), 'usr
', and 'bin
', and a leaf node 'wc
', which is an ordinary file. In a JNDI namespace, these would be represented by three contexts and a reference.
Other naming systems use different notational conventions. For example, the DNS naming system uses dots to separate contexts: java.sun.com. The JNDI can be used to represent, or implement, any hierarchical naming system.
References and contexts are Java objects, and so they can have attributes, or properties, associated with them. For example, a file in a file system typically has a creation date, a last-modified date, and a set of attributes that tell who can read, who can modify, and, if possible, who can execute the file. In an analogous way, references and contexts in JNDI can have attributes. The OSE uses these attributes to encode permissions (read, write, execute), and to store configuration parameters for services, domains, and servlet contexts.
In this guide the JNDI-specific term "context" is frequently used. However, since a context is quite analogous to a directory in a file system, the more imprecise term "directory" is sometimes used. For example, it seems clearer to talk about a "servlet context directory" in the JNDI namespace, rather than the redundant "servlet context context", when mention must be made of the specific object that contains a servlet context.
The JNDI provides API functionality that can bind objects to named contexts or references, and unbind the name from the context or reference.
In the OSE, these names make up the namespace. Binding is a JNDI operation that associates a name with the information required to construct an object. When you give a name to a file in a file system, you are in effect binding the name to the object: the file.
As you will see in following sections, the OSE/OJVM session shell provides tools that use the JNDI bind to associate names in the OSE namespace with servlet classes loaded into the database.
There are two components that make up JNDI. The application programming interface, or API, implements the classes that allow the user (for example, a tool implementer) to access and navigate the namespace. The interfaces and classes that make up this API are provided by Sun.
A servlet container developer who wants to make JNDI available for use in an application must also implement the Service Provider Interface (SPI), to allow the API to access a specific set of objects that are stored somewhere. The objects might be stored in a file system, or in a database table, or perhaps even in a flat file on a disk. It does not matter how or where the objects are ultimately stored, as long as they can be accessed through the SPI.
Note that the storage does not need to be hierarchically organized. For example, a (non-object) Oracle table contains rows, but does not offer a tree-like structure. Nonetheless, it is quite feasible to interface a tree-like hierarchical namespace to a database table by writing the appropriate JNDI SPI. Figure 2-1 shows the relationship of the various components that participate in a JNDI-based application and its container.
JNDI also provides for a namespace whose root references one storage system (that is, uses one SPI) to contain one or more contexts that refer to different storage systems, that use one or more different SPIs. The second and other namespaces are federated with the root namespace in this case. The transition from one namespace to a federated one is usually transparent to the application user.
However, the OSE developer or administrator needs to understand the concept of federated namespaces, as they are used in most Web applications. For example, the document root (doc_root
context) in an OSE/OJVM application is typically an object that is a link to a federated OS file system.
Figure 2-2 shows an example of the contexts that might be found in the root of the JNDI namespace in an OJVM.
The following table describes briefly the function of each of these contexts.
When you create a new Web service, you normally place the service root in the root directory of the JNDI namespace.
Before developing and configuring a Web application that runs under OSE/OJVM, you must have available an HTTP service, with a specified service endpoint (TCP/IP socket). For example, a URL such as
http://Oratest:8088/myPage.html
specifies a connection to a TCP/IP port (or socket), number 8088. If the URL does not specify a port, the default port for the HTTP presentation, usually port 80, is assumed.
The endpoint is used by the dispatcher to connect to the HTTP service. See "Creating a Web Service" for information about services and setting up a service endpoint.
There are two routes that an incoming HTTP request from an HTTP client, such as a Web browser, can take to connect to the OSE, and invoke a servlet or JSP:
mod_ose
Oracle strongly recommends that you connect to servlets and JSPs by going through the Oracle HTTP Server (Apache), and using the mod_ose
Apache module to connect to an Oracle listener and then the OSE. See "Connection Using the Oracle HTTP Server as Listener" for the benefits of this approach. For information about Apache and mod_ose
see Chapter 4, "An Apache Module for OSE".
However, for occasional debugging purposes, it is possible connect to the OSE directly, by registering a service endpoint with the Oracle listener (or even directly with a dispatcher), and connecting to that port.
Figure 2-3 shows some of the various ways that an HTTP client can connect to an Oracle9i server.
A large Web application might have many static pages, in combination with servlets and JSP pages to serve the dynamic content. This kind of application will run more efficiently if the static pages are served directly from a file system, using a server running either on the middle tier or the data tier, and the dynamic pages are served by the OSE running in the Oracle server.
In this case, configure the application so that connections to servlets and JSP pages are routed to the OSE running in the database using the Apache module mod_ose. See Chapter 4, "An Apache Module for OSE" for information about mod_ose
, and instructions on how to configure it.
Another reason to use Apache and mod_ose
is because applications that make heavy use of stateless requests can place a heavy load on an Oracle server, if they connect directly to an Oracle listener. Each stateless request that comes directly to the Oracle server's OSE causes a new server session to be started, with the attendant overhead. But when using Apache with mod_ose
, stateless requests are in effect pooled, each Apache with mod_ose
process keeping a stateless connection to the server and OSE open. This allows much better throughput and scalability.
With a direct connection, the client request is first routed to the Oracle listener running on the host named in the URL. For example, a URL from a browser starts with the string http://Oratest:8088/...
. The domain name servers that the client system is using will look up Oratest
, and substitute the appropriate 32-bit Internet address, for example 10.10.10.5. The request is then routed to the listener on that host system. If no listener is running on that host, an error is returned. The error is returned to the client is an HTTP 500 error. Different clients, such as different Web browsers, might handle the error in different ways, for example by displaying a "failed to connect" message.
An existing listener must then route to a service registered on the endpoint at port 8088. If no service is registered on that port, the listener returns to the client an error indicating a failure to connect. But if a service is registered, the service is started. For OSE, the Oracle JVM is started, and then the OSE is started to route the request to the appropriate servlet named in the remaining part of the URL (the URI). Routing to a servlet is explained in detail in "Finding the Servlet".
If you want HTTP client requests to go to an Oracle dispatcher directly, bypassing the listener, you direct your client to the dispatcher's port number. Do one of the following to discover the dispatcher's port number:
mts_dispatchers="(address=(protocol=tcp | tcps)
(host=< server_host>)(port=<port>))
(presentation=oracle.aurora.server.<http_service_name>)"
The attributes are described below:
Specifies the network address that the dispatchers will listen on. The network address may include either the TCP/IP (TCP) or the TCP/IP with SSL (TCPS) protocol, the host name of the server, and an HTTP listening port, which may be any port you choose that is not already in use.
The client supplies the port number on its URL, as follows:
http://<hostname>:<portnumber>
Notice that the URL excludes a SID or service name. The dispatcher does not need the SID instance or service name because it is a directed request.
The PRESENTATION enables support for HTTP. For an HTTP presentation, use the HTTP service name that you established with the createwebservice
command, for example
http://testService
Notice that the URL excludes a SID or service name. The dispatcher does not need the SID instance or service name because it is a directed request.
An Oracle9i server can present many different services to a client. The most common one are:
Clients that follow the traditional client-server model, perhaps with a client running an OCI or a Forms application, connect to the TTC Oracle service. (TTC is a traditional Oracle abbreviation that stands for "two-task common".)
Remote clients that call Enterprise JavaBeans or CORBA objects in the server connect to a service that supports session IIOP connections.
Web-based client applications connect to an HTTP service on the Oracle server.
Some developers are able to write customized special services, that can support an arbitrary communications protocol, and provide database services beyond the scope of those offered by standard Oracle9i server. Writing custom services is not covered in this document.
Oracle9i provides installed support for HTTP services. A single system can support one or more Web services, with different endpoints. For example, an e-business that sells a range of products might want to install several Web services, each supporting a different product line.
A Web service is associated with an endpoint. An endpoint is a port to which the HTTP client can send incoming requests. When you register a Web service you must specify the endpoint for the listener. For the TCP/IP connections that all HTTP requests use, the endpoint is a socket number. 80 is the usual default socket number for HTTP requests. Secure Socket Layer (SSL) connections would use a different port, perhaps 90.
Only a user with Oracle SYS privileges can establish a Web service and a service endpoint for an Oracle server. Severe security problems could arise if non-privileged users were able to establish new Web services.
The Oracle Servlet Engine supports two kinds of Web service: single-domain and multi-domain. A single domain Web service supports a single Web domain. In a single-domain Web service, the port (endpoint) is the sole determiner of the routing of servlet request to service and then the domain.
There are several kinds of multi-domain services. Multi-domain services are also called virtual hosting.
For many purposes, a single-domain service is all that is required. However, in many cases a single server machine must host multiple Web domains. For example, a single system that is required to host an administrative domain and an application domain, each with entirely different sets of privileges and applications. Or, a single server system might be required to host users on the intranet as well as users connecting from the internet, outside the firewall. In the latter case, the server system will typically have two or more physical network connections, and each network interface card can support a separate Web domain.
Support of multiple Web domains is called virtual hosting. There are two types of virtual-hosted service:
Because it is possible for a Web domain that is served by an IP address to have multiple domain names (multiple entries in the DNS tables), it is possible to combine case 1 above with case 2. For example, a server system could have three network interface connections, two of which support single Web domains, and a third that supports multiple (name-based virtually-hosted) domains.
The OSE/OJVM supports virtual hosting differently from a purely JDK-based implementation of servlet containers, such as Tomcat or JServ. See "Virtual-Hosted Services" for more information.
You can also find more information on setting up single and multiple Web domains in Chapter 3, "OSE Configuration and Examples".
The system administrator or DBA uses the createservice
or the createwebservice
session shell commands to establish a service for the OSE, and identify its
The administrator must be connected to the session shell as SYS to use either of these service creation commands.
The createwebservice
command is a more specific form of createservice
, and can only be used to create HTTP-based services. For information about the more general createservice
command, see the Oracle9i Java Tools Reference.
Once a service is created, the administrator must establish service endpoints on which the service can listen, using the addendpoint
session shell command.
See "Creating a Web Service" for specific instructions on how to create a new Web service, and add listening endpoints for it.
The OSE JNDI namespace contains a service
"directory" at its root. Objects of type SERVICE
exist in /service
, one for each Web service that has been created for the Oracle instance. For example, a newly installed Oracle9i server with the JVM has a /service
context that includes the following services:
The admin
service is required for proper operation of the OSE, and must not be removed. The HRService
is installed as part of the OSE demo set.
Each SERVICE
object in the /service
context contains a set of property groups that describe the service. These include
Most of the property values in the SERVICE
object are set by the createservice
or createwebservice
command, and by the addendpoint
command, either as defaults or from the parameters of the commands.
You can use the session shell getproperties
command to list the properties for a SERVICE
object.
An HTTP Web service can support one or more than one Web domain. The Web domain is the basic organization unit of the Web service, and contains the servlet contexts into which applications are loaded. Web domains correspond either to service roots, to DNS domain names, or to IP addresses of that host, depending upon how the Web service is configured (single- or multi-domain).
Each Web domain that a service supports has a name: the domain name. The domain name is the same as the name of the Web service root in the most common case--a single-domain Web service.
In the OSE/OJVM, a Web domain is owned by a database schema. For example, user HR might own the /HRRoot
Web domain, where /HRRoot
is also the root of a single domain service.
Every Web domain context contains a config
object in the JNDI namespace. The domain also contains a contexts
directory and a logs
directory. A single-domain service Web root also has a servicelogs
directory, but that is for the Web service, and is created by the createwebservice
command.
Figure 2-4 shows the JNDI namespace after the creation (as shown above) of a single-domain Web service and the corresponding Web domain.
The remainder of the Web Domains section of this Guide explains multi-domain Web services. If your application uses only a single-domain service, you can skip ahead to "Servlet Contexts".
A multi-domain (also called virtual-hosted) Web service can support more than a single Web domain under a single service. There are three kinds of virtual-hosted service:
abc.com
and abc.us.com
) for different Web domains. These are name-based virtual-hosted services.
A Web server/servlet engine combination such as Apache/Tomcat supports multi-domain Web services in two ways. There can be a separate servlet engine process for each Web domain, each perhaps configured differently. Or, for some cases, a single process can support virtual hosting. (This can run into OS limitations if there are a large number of virtual hosts.)
With the OSE/OJVM, however, there is no reason or need to have multiple Oracle instances running to serve different Web domains. The Oracle JVM is capable of supporting multiple Web domains, and has proven to scale well when doing so.
So the OSE/OJVM allows you to configure an Oracle servlet engine to support multiple Web domains and/or multiple IP addresses, all running in the same server instance.
Name-based virtual hosting is used to handle the case in which multiple DNS domain names resolve to the same IP address, and multiple Web domains are needed to service each domain name.
For example, you might have the following domain names
all resolving to the IP address 10.5.5.10.
In the OSE/OJVM you handle name-based virtual hosting by establishing a separate Web domain under a single service root. The name of the Web domain must be the same as the DNS-recognized hostname that is used in the request URL.
See "Determining the Web Domain" for information about how the OSE processes these URLs to route requests to the correct Web domain.
In some situations it is a requirement that a single system support multiple IP addresses. The usual case is that the machine has multiple network interface cards (NICs), but virtual interfaces (also called "ip aliases") could also be used.
In the OSE/OJVM, you create an IP-based virtual-hosted service by establishing separate Web domains under the service root. The names of the Web domains are exactly the same as their corresponding IP addresses, and are directly under the service root.
How are these Web domains accessed in the URL? They are accessed by using the IP addresses as the domain names in the URL. For example, the request URL
http://10.5.5.10:8080/
could reach the Web domain at /MHHost/10.5.5.10
.
Note the difference between the URL http://10.5.5.10:8080/
in a single-domain case, and the URL used to access the IP-based domain 10.5.5.10
above. In the single domain case, the IP address in the URL is used to reach the server, via the DNS mappings. In the IP-based virtual host case, the IP address of the network interface is used to determine the correct Web domain.
When you set up a service that supports both IP-based and name-based virtual hosts, the name-based Web domains are in effect embedded in the IP-based domains. See Figure 2-8, where for example the Web domains def.com
and ghi.com
are contained within the IP-based domain 10.5.5.11
.
In the case of embedded Web domain, it is only necessary to use the createwebdomain
command to create the "leaf" domains, that is the domains that are used, and that must contain a valid config
object, a valid /contexts
directory, and so on. So for example, to set up the Web domains for the virtual-hosted service shown in Figure 2-8, you use the session shell mkdir
command to create the non-leaf domains, and use createwebdomain
only for the terminal domains. Using createwebdomain
to create the IP domains would not result in errors at run time, but it would create unnecessary objects in the JNDI namespace that are never accessed.
Here are example commands that you might use to set up the four Web domains for the service shown in Figure 2-8:
$ cd $ createwebservice -root /ServiceRoot -ip -virtual IPservice $ # add endpoints and chown, not shown $ mkdir /10.5.5.10 $ mkdir /10.5.5.11 $ createwebdomain -docroot /tmp/testService1 /10.5.5.10/abc.com $ createwebdomain -docroot /tmp/testService2 /10.5.5.10/10.5.5.10 $ createwebdomain -docroot /tmp/testService3 /10.5.5.11/def.com $ createwebdomain -docroot /tmp/testService4 /10.5.5.11/ghi.com
In the case of a multi-domain Web service, the OSE must determine which Web domain in the Web service the request URL should be directed to. There are four pieces of information that the OSE can use to determine the Web domain:
http://
protocol indicator and before the next forward slash ('/'). The host part of the complete URL
http://myHost.co.uk:8080/ose/testServlet
is
myHost.co.uk:8080
where :8080
specifies the port number.
/service
context of the JNDI namespace.
Note that if the service is not virtual hosted, it must be single domain, and the Web domain is simply the service root.
The algorithm used to determine the Web domain for a request to a multiple domain Web service is the following:
This section demonstrates how the OSE processes a URL to find the Web domain. Four cases are shown, one for each of the four Web service types: single-domain, name-based virtual-hosted, IP-based virtual-hosted, and both IP-based and name-based virtual-hosted.
In each case, two URLs are processed:
The IP address passed to the OSE for each of these examples is always 10.5.5.10
.
Figure 2-5 shows request processing for a single-domain Web service. The IP address available to the OSE outside of the URL is ignored, because it is a single-domain service, but either form of the host name in the URL--using the DNS host name or using the actual IP address, direct the requests correctly to the single Web domain.
Figure 2-6 shows an example of a name-based virtual hosted service, with two Web domains. The Web domains are named abc.com
and 10.5.5.10
, as shown in the JNDI namespace. The interesting thing about this example is that the domain named 10.5.5.10
is reached by name, and not by the entirely incidental fact that the service IP address also happens to be 10.5.5.10
. This is because the service type does not include IP-based virtual hosting, so the OSE ignores the actual NIC IP address.
Figure 2-7 shows an example of an IP-based virtual-hosted service. There are two separate Web domains, named 10.5.5.10
and 10.5.5.11
. Since the requests are incoming on the IP address 10.5.5.10, both requests are serviced by the Web domain named 10.5.5.10
.
Figure 2-8 shows the request processing when the service is configured for both IP-based and name-based virtual hosting. This example is a somewhat contrived case, as there is a name-based virtual-hosted Web domain called 10.5.5.10 that is in fact nested under the IP-based Web domain also called 10.5.5.10. Although it would be unusual to set up a Web service with this configuration, it is perfectly legal to do so.
This section describes the OSE servlet context. It includes the information you need to understand how a servlet context governs a Web application. For specific information about creating and configuring a working servlet context, and for examples of session shell commands to do this, see "Creating Servlet Contexts".
A servlet context holds a Web application that is loaded into the OSE. The servlet context contains the servlets that make up the application, as well as other objects that the application needs. These might include JSPs, image files, sound files, static HTML pages, and other objects that make up the application.
You should create at least one servlet context for each discrete application that the Web domain supports.
A servlet context belongs to a specific Web domain. When you create a servlet context, you must specify the Web domain for the servlet context. A servlet context is a self-contained namespace in the JNDI namespace. All servlets in the context have a published name, and the name is published in a single context (directory) in the JNDI namespace for the servlet context. So no two servlets in a servlet context can have the same name.
The servlet context maintains certain static information about the context. Each servlet context has a configuration object, named config
, that is located in the root of the servlet context. The config object has property groups that provide information about things such as what languages and character sets servlets will accept, what MIME groups are supported, and the servlets that the application contains. See "Configuring a Servlet Context" for specific information about the config
object.
When you create and maintain a servlet context, you must keep two concepts distinct: the servlet class and the servlet published name. The class is
.class
file that results when you compile the Java servlet source on the client system
loadjava
command)
publishservlet
command
The published name is the reference to the class that is stored in the named_servlets
directory of the servlet context when you publish the servlet, using the publishservlet
session shell command, or when you deploy an application using a WAR file.
Each servlet context has the following:
When a Web domain is first created, only one servlet context is created with it: the default context. Applications should not run under the domain default context. The default context is there to handle cases where a URL specifies a domain, but no path to a servlet context or a specific servlet in the context. In that case, the default context can serve a default page.
A newly-created servlet context has the namespace structure shown in Figure 2-9.
To make your servlets available to HTTP clients and to other servlets you must first load them into the Oracle server, and then publish them to the JNDI namespace. All lookups of servlet references (such as in URLs) are done through the JNDI namespace.
You use the loadjava
operating system command to load the servlet to the Oracle server. Use the publishservlet
session shell command to publish a servlet to the JNDI. See "Publishing Servlets" for specific instructions about servlet publication, and examples.
When configuring the servlet context, you should understand how the OSE processes a URL sent in by an HTTP client, to find the right servlet context and the servlet in the context. Within a Web domain, a servlet is located by
The published name of the servlet may or may not be the same as virtual path name. This allows considerable configuration flexibility, as the same servlet can be reached by different paths.
The Uniform Resource Locator is part of the request that the client sends to the OSE. A URL consists of three or four main parts:
Figure 2-10 shows graphically the format of a typical URL request.
The protocol is the initial part, delimited by a colon and two forward slashes. The protocol for all requests accepted by the OSE must be http://
. (Other protocols, accepted by different services than those the OSE supports, might be ftp://
, or sess_iiop://
.)
The host name and port number determine the Web service and the Web domain to which the request is to be forwarded. Every thing after the port number, or after the hostname if the port number is missing (and thus is defaulted), is the URI. The URI contains
These are shown in the lower parts of Figure 2-10. In this example, the remaining material in the URI consists of a query string.
The method that the OSE uses to determine the correct Web domain was described in the section "Web Domains".
The contexts
property group of the Web domain config
object contains the virtual path mappings for each servlet context in the domain. For example, if HRContext
is the name of a servlet context in the HRRoot
domain, then the config
object for the HRRoot
domain might contain an entry such as:
--group--=contexts /ose=HRContext
where /ose
is the virtual path mapping for the HRContext
servlet context. The virtual path mapping for the servlet context is set by the -virtualpath
parameter of the createcontext
command.
When the OSE processes a URI, it looks for the longest possible match to find the servlet context. So for example if a Web domain contains two servlet contexts, one having a virtual path mapping /ose
, and the other a virtual path mapping /ose/test
, and the URI is .../ose/test/servlet1/
, then the OSE looks for a servlet with the virtual path servlet1
in the servlet context whose virtual path mapping is /ose/test
. In this case the OSE does not look for a servlet with the mapping /test/servlet1
in the servlet context whose virtual path mapping is /ose
.
The virtual path of the servlet itself is specified in the publishservlet
session shell command. It cannot be null, as the servlet virtual path is the name that the OSE uses to find the servlet in its context.
If the OSE finds no servlet virtual path in the URI, then the default servlet for the context, or for the domain, is activated. The following example should clarify this.
Assume that you have set up the following
testService
on host Oratest
, that listens on endpoint 8088
/testRoot
testRoot
oseContext
and testContext
/ose
is assigned as the virtual path for the oseContext
servlet context
/ose/test
is assigned as the virtual path for testContext
oseServlet
is loaded into the database, and published to the oseContext
servlet context as Servlet1
, with the virtual path name /test1
simpleServlet
is loaded into the Oracle database, and published to the testContext
servlet context as Servlet1
, assigning it the virtual path /simple
Figure 2-11 shows a view of the relevant parts of the OSE JNDI namespace as configured for this example.
Figure 2-12 shows how the OSE resolves the URL
http://Oratest:8088/ose/test/test1
to instantiate the servlet servlet1
in the oseContext
servlet context, given the configuration listed in Example 2-1.
The OSE processes the URL with the following steps:
Oratest
) and the port number (8088).
testRoot
. This is determined by the properties in the /service/testService
object (the configuration object for the testService
).
config
object for the testRoot
domain, the OSE finds that the virtual path /ose/test
maps to the testContext
servlet context. This mapping is in the contexts
property group of config
.
testContext
servlet context, the config
object maps the virtual path /test1
to the reference servlet1
in the named_servlets
directory.
simpleServlet
, and passes it the URL, parsed into its components (URI, context info, PathInfo).
/testRoot/contexts/default.
According to the Servlet 2.2 specification, entries in the context.servlets
property can be paths or wild-card names. Partial paths have priority over wild-card names. Exact matches have priority over both partial paths and wild-card names.
If no match for the requested URL is found, the OSE looks for a servlet named defaultservlet
, first in the servlet context directory, next in the Web domain directory, and then in the Web service. If the default servlet is found, it processes the request. If no default servlet is found, OSE generates an internal error code.
This example shows the effects of four different servlet context virtual path mappings. There are three servlet contexts, cleverly named ServContext1
, ServContext2
, and ServContext3
. The fourth case has a null mapping. The virtual path mappings are:
Assume that the URI in the request URL is /abc/def/ghi.html
. Here is what will happen in each case:
/def/ghi.html
is searched for in ServContext1
. If found, it is activated.
/ghi.html
is searched for in ServContext2
. If found, it is activated.
ServContext3
is activated.
When a servlet needs to communicate with the database, it uses JDBC and an Oracle JDBC driver. There are three basic kinds of JDBC drivers available with Oracle9i:
The OCI driver is used by thick clients who are connecting through Oracle Net to a server.
The server-side internal driver is used by a servlet when accessing the database in the same instance that the servlet is running in. This driver provides a fast, in-memory path to the SQL data, as no network connectivity is required when using this driver.
To connect using the server-side internal driver, first make sure that your servlet code imports the java.sql
and oracle.jdbc
packages, as follows:
import java.sql.*; import oracle.jdbc.*;
Use the defaultConnection()
to connect. No connect string is required, as the connection is always the same:
Connection conn = null; try { // connect with the server-side internal driver OracleDriver ora = new OracleDriver(); conn = ora.defaultConnection(); ...
For a complete examples that use the server-side internal driver to access the sample schema HR.EMPLOYEES table, see "Creating a Servlet", and "EJB".
The thin driver is used by Java applets on the client side, and is also used by servlets and JSPs when connecting from one database instance to another. So if you have a servlet running in one instance, and need to call an EJB, or a CORBA object, or another servlet that is running in a different instance, use the JDBC thin driver.
|
Copyright © 1996-2001, Oracle Corporation. All Rights Reserved. |
|