Oracle9i Servlet Engine Developer's Guide Release 1 (9.0.1) Part Number A90213-02 |
|
This chapter describes how to set up and configure applications to run in the Oracle Servlet Engine under the Oracle JVM. Also included are many examples that show the configuration steps, and some demo servlet applications.
Accessing servlets in the OSE/OJVM by going through the Oracle HTTP Server (powered by Apache) and the mod_ose
module requires additional configuration steps. Chapter 5, "Configuring mod_ose" describes these steps.
This chapter contains the following topics:
The OSE runs in a virtual JVM inside an Oracle (database) server session. You must be running an Oracle shared server configuration to run the Oracle JVM, and hence to use the OSE. There are three ways that an HTTP client can access a servlet or JSP in the OSE:
mod_ose
to the Oracle Servlet Engine in an Oracle (database) server
The first of these possibilities can be useful for debugging, or for quick testing of deployed servlets. But because it does not provide adequate scaling when multiple clients are involved, it should never be used when developing or testing production applications.
The second possibility can serve when your application consists solely of stateful servlets or JSPs. This, however, is true of few applications.
The third possibility is the one that Oracle recommends for all applications. Static HTML pages and other static data are served from the Oracle HTTP Server, and requests for dynamic content are routed through mod_ose
to the OSE. To set up your application to run in this mode, there are additional configuration steps that you must perform. For example, you must configure the Apache mod_ose
configuration file ose.conf
to indicate which requests will be routed to the OSE. See Chapter 4, "An Apache Module for OSE" and Chapter 5, "Configuring mod_ose" for information about configuring mod_ose
.
It is also possible to use the Oracle HTTP Server with mod_ose
to connect to OSE applications with a server configuration that does not normally use shared servers. See "Non-Shared Server Installations" for more information.
Configuring the Oracle Servlet Engine itself and an application that is to run in the OSE requires some or all of the following steps:
TNSNAMES.ORA
file or an LDAP configuration file
Not all of these steps are required in all cases. For example, steps 1 through 7 will not be required to run most of the sample applications that come with this OSE release. You might need to perform steps 1 through 3 or 4 only once for all your application requirements.
The OSE/OJVM runs in a "virtual JVM" in the Oracle server. As with any other application that uses the OJVM, you must be running the Oracle shared server to use the OSE.
The shared server is configured in the server initialization file (traditionally called INIT.ORA file). Entries such as
shared_servers=5 dispatchers="(PROTOCOL=tcp)"
are typically found to indicate that a shared server configuration, with associated dispatchers, is in effect for the instance.
When you are using the Oracle HTTP Server (Apache) together with mod_ose
to access the OSE, you might need to configure the TNSNAMES.ORA file. If this file contains an entry called inst1_http
, you can use that Oracle Net entry for mod_ose
. If it does not, you must configure a descriptor for mod_ose
. See "Oracle Net and Oracle Listener Configuration".
This section describes how to create a single-domain OSE Web service. Later sections describe how to configure a Web domain for the service, and how to create servlet contexts and publish servlets in the domain.
In order to access servlets in the OSE, you must have created a service to handle incoming HTTP requests, as well as a Web domain in which the servlets can run. The service runs in the Oracle server. An Oracle server can support more than one service. For example, you might configure an OSE to serve administrative HTTP requests from one service, and application servlet requests from separate service. You can set up the administrative service so that it has additional privileges not available to the normal application Web service.
There are two session shell commands that the SYS user must issue to create a Web service: createwebservice
and addendpoint
.
To remove an existing Web service, the SYS user issues the destroyservice
session shell command. To remove an existing endpoint, use the rmendpoint
command. See "Examples" to see how the two commands are used.
Issue the createwebservice
command from the session shell. The syntax for this command is
createwebservice -root <location> [optional_parameters] <service_name>
The parameters of the command are
The addendpoint
command is used to specify the endpoints (port numbers) on which a service listens. The syntax for this command is
addendpoint -port <port_number> [optional_parameters] <service> <endpoint_name>
The parameters of the addendpoint
command are
As always in this Guide, '%'
indicates an operating system prompt, and '$'
indicates a session shell prompt.
Here are examples of the commands that you can use to create a single-domain service named testService
, and add named endpoints to it:
$ createwebservice -root /testRoot testService # $ addendpoint -port 8088 -register testService TestPublic $ addendpoint -port 9088 -register -ssl testService TestSSL $ addendpoint -net8 -register testService TestNet8
This example adds two dynamically-registered endpoints for connection through an Oracle listener, on ports 8088 and (for SSL) port 9088. The last endpoint is for access to OSE from Apache and mod_ose
, which uses the normal Oracle Net TTC. If you always connect using mod_ose
, as recommended by Oracle, you only need to use the last addendpoint
command.
The following session shell commands (issued as SYS) show how to make the HR schema the owner of his service:
$ cd $ chown -R HR /testRoot
Use this command to remove a previously established endpoint.
The syntax is:
rmendpoint [-force] <service> <name>
where the <service>
is the name of the service that the endpoint was originally established for, and <name>
is the endpoint name that was used in the addendpoint
command.
If this command results in errors, or does not seem to remove the endpoint (shown by errors when trying to create a new endpoint of the same name on the same service), use the -force
option. It never hurts to use -force
.
After creating the service, you can examine the properties of the service using either the getproperties
command, or more specifically the getgroup
command, to examine the properties of the service
group of the newly-created testService
service. In the createwebservice
example command above, notice that neither the name-based virtual-hosting (-virtual
) nor IP-based virtual-hosting (-ip
) options are specified. This means that neither service.http.virtual-host
nor service.http.multi-homed
properties are present in the service
property group of the testService
service. You can verify this by issuing the commands
$ cd /service $ getgroup testService service
You can change properties of the service using the addgroupentry
session shell command, but you must be careful if you do this. Changing properties at random, without a real understanding of their function, can cause the service to malfunction or to stop working completely.
Some service properties that you might need to change are:
service.globalTimeout
(service timeout value in seconds)
endpoint.<endpoint_name>.timeout
(endpoint timeout value in milliseconds)
See "Virtual-Hosted Services" for general information about multi-domain Web services. To create a multi-domain service, the SYS user issues the session shell command createwebservice
, just as for a single-domain service. The difference is that either the -ip
or the -virtual
options are used. Both options are used to create a Web service that supports both IP-based and name-based virtual hosting.
Here is an example of session shell commands that create Web domains for a name-based virtual-hosted service:
$ createwebservice -root /vhost -virtual vhostService $ addendpoint -port 8011 -register vhostService ep8011 $ createwebdomain -docroot /private/youruserID/test/docsv1 /vhost/xyz.com $ createwebdomain -docroot /private/youruserID/test/docsv2 /vhost/xyz.us.com
Note that each Web domain under /vhost
has the same name as a separate DNS domain name. Now the request URLs
http://xyz.com/
and
http://xyz.us.com/
will be served by different Web domains. One domain might be used for one of a company's product lines, the other Web domain to support a different part of the company.
Consider a system that has two network cards. The network interfaces are configured to the IP addresses 10.5.5.10 and 10.5.5.11.
Configure an OSE to support these three network interfaces, each having a separate Web domain, using the following session shell commands:
$ createwebservice -ip -root /MHhost MHService
Note the properties that are established for the MHService:
$ cd /service $ getproperties MHService --group--=service service.name=Service MHService service.description=Aurora HTTP Servlet Engine service.version=1.0 service.vendor=Oracle Corp. service.globalTimeout=60 service.root=/MHhost service.presentation=http://MHService service.error.log=servicelogs/error service.event.log=servicelogs/event service.http.multi-homed=true ...
The last property in this abbreviated list is the one that determines that the Web service supports IP-based virtual hosting.
Now create the domains:
# the backslash is a line-continuation character $ createwebdomain -docroot /private/youruserID/test/docs010.005.005.010 \
/MHHost/10.5.5.10 $ createwebdomain -docroot /private/youruserID/test/docs010.005.005.011 \
/MHHost/10.5.5.11
$
Before creating one or more Web domains, first create the Web service that hosts the domains. See "Creating a Web Service" for instructions.
The single-domain Web domain has a name that is the same as its service root. For example, you created a single-domain service in the example above with the root /testRoot
. To create a Web domain under this root, use the createwebdomain
session shell command.
When you create a Web domain, you specify a document root, using the -docroot
parameter. This is a place in the file system on the server's system from which the OSE serves static pages. For example, on a UNIX system create a directory such as /private/youruserID/test/docs
. Put an HTML file, perhaps welcome.html
, in that directory.
Files in the OS filesystem have access permissions that are associated with the operating system users, for example UNIX or Windows NT logins. But for the OSE to access files in the OS file system, the files must have Java file permissions for the database user who is trying to access the file.
You assign the files Java access permissions through SQL commands. The permissions are assigned to database users, not to OS logins. Use the grant_permission
procedure in the dbms_java
package to grant (or restrict) Java permissions (java.io.FilePermission
) on files in the operating system.
See the Security chapter in the Oracle9i Java Developer's Guide for more information about Java file permissions.
Here is an example that creates a Web domain, using the session shell:
$ createwebdomain -docroot /private/youruserID/test/docs /testRoot
On a Windows NT or Windows 2000 system, create a directory such as C:\test\docs
, and issue the create command as:
$ createwebdomain -docroot C:\test\docs /testRoot
To set the file permissions, use SQL*Plus. For example, to assign read and write permissions to the HR user for the doc_root /private/youruserID/test/docs
(and all subdirectories of it) of the createwebdomain
example above, enter SQL*Plus as the SYS user and issue the command:
SQL> call dbms_java.grant_permission('HR', 'java.io.FilePermission',
'/private/youruserID/test/docs/*
', 'read,write');
Once you have established the service, and a service endpoint, the OSE can always access this domain directly. For example, the URL
http://Oratest:8080/
will access the /testRoot
domain as long as these conditions are met:
Oratest
, and the OSE/OJVM is installed
Oratest
and substitute the correct 32-bit IP address for it, so that the request can be routed to the correct machine
In this example, the hostname part of the URL is only used by the DNS servers. The OSE receives the complete URL, as well as the IP address, but does not need to process either to find the Web domain. There is only one Web domain established for that service.
Some machines have multiple entries (multiple host names) in the DNS namespace for the same IP address. For example, the hostnames Oratest
and Oratest.us.oracle.com
might map to the same address. (On UNIX-like systems, this can be seen in the /etc/hosts
file.) Assume that the IP address in this case is 10.5.5.10. So, given the create service and create Web domain conditions above, each of the following URLs gets a request to the same OSE Web domain on the Oratest
machine:
http://Oratest/ http://Oratest.us.oracle.com/ http://10.5.5.10/
(In this case, the default servlet for the testRoot
service is activated by these URLs.)
Before creating a servlet context, you must establish a Web domain in which the context will exist. See "Creating Web Domains".
There are two ways to create and configure a servlet context for the OSE:
This chapter uses the session shell commands in examples, because they show finer-grained control of the servlet context. See Chapter 8, "Oracle WAR Deployment" for information about deploying an application using WAR files.
In the session shell, use the createcontext
command to create a servlet context. The syntax of this command is:
createcontext -virtualpath <path> [options] <domain_name> <context_name>
where the options are
[-recreate]
[-properties <prop_groups>]
[-docroot <location>]
[-stateless]
Here is an example that uses this command to create a servlet context named HRRoot
in the /HRRoot
Web domain:
$ createcontext -virtualpath /ose/hr -docroot /private/hr/test/html
/HRRoot HRContext
The command parameters and options are:
-virtualpath |
This is a required parameter, not an option. Use it to specify a path in the URL that precedes the servlet path. See "Finding the Servlet" for more information about how the OSE processes the URL, and finds the right servlet context and servlet. The minimum |
<domain_name> |
The JNDI name of the Web domain that the context is to be located in. The domain name should be an absolute path. For example, a Web domain in a virtual hosted service (both IP- and name-based) might be |
<context_name> |
The name you give the servlet context. This name is arbitrary. It is used when you configure the context, publish servlets to the context, and when you finally destroy the context. |
-docroot |
Specify the location in the file system of the computer on which the OSE runs where static files (such as HTML files) are kept. The docroot must be specified as an absolute path. |
-recreate |
If a context with this name already exists, delete it before adding an empty context with this name. Doing this destroys any servlets that were associated with this context before the present |
-properties |
<prop_groups> List of property groups to use as the defaults for this service. Specify the name-value pairs in the same way as in the |
-stateless |
All servlets in this context are stateless. Contexts declared to be stateless can contain only servlets that are stateless. Stateless servlets never try to access the |
When you create a servlet context, the root context has a config
object. By default, this object has the property groups and property/value pairs shown below, for the HRContext
that was created in the previous example:
$ cd /HRRoot/contexts/HRContext $ getproperties config --group--=context.properties context.browse.dirs=true context.welcome.names=index.html:index.htm context.accept.charset=ISO-8859-1 context.accept.language=en context.default.languages=* context.default.charsets=* --group--=context.params --group--=context.mime java=text/plain html=text/html htm=text/html body=text/html --group--=context.servlets /errors/internal=internalError --group--=context.error.uris 401=/system/errors/401.html 403=/system/errors/403.html 404=/system/errors/404.html 406=/system/errors/406.html 500=/errors/internal
You must configure the new context so that it has the properties that are appropriate for your application. Do this by using the accesslog
and the addgroupentry
session shell commands.
This command specifies how HTTP access logging is handled for the servlet context. Access logging records information about each incoming HTTP request. The syntax for the accesslog
command is:
accesslog [options] <context_name>
[-trace]
[-systable
[-table <table_spec>]
For more information about the required logging tables, see "Logging".
Use this command to add or change the values for properties (in property groups) in the config
file. The syntax for this session shell command is:
addgroupentry <object_name> <group_name> <property_name> <property_value>
The parameters for this command are:
You can add the following propertiesto the servlet context config
object:
context.browse.dirs |
If "true", allows the response to list the files in a directory, when the URL ends with a '/'. |
context.debug |
If "true", sends debug output to the console. |
context.default.charsets |
The charset(s) that are supported. |
context.default.languages |
The two-letter standard abbreviation for the languages that are supported. Following the HTTP specification. |
context.default.timeout |
The timeout for all servlets in the servlet context. The value is in seconds. |
context.runAsOwner |
Allows servlets in the servlet context to run with the permissions of the JNDI owner of the context, rather than inheriting the permissions of the web domain owner. See "Run As Owner" for more information on using this property. |
The context.mime
property group lists the MIME types supported by the context.
The context.servlets
group contains the virtual path mappings for each published servlet in the context.
The context.error.uris
group shows the mappings for HTTP errors to HTML files, or other files that the OSE responds with when the error occurs.
The OSE logs events and errors. By default, logs are directed to the JAVA$HTTP$LOG$
table in the database, which is in the SYS
schema. If your application requires that you process and have available the logs of events (HTTP requests, for example), and errors (and this is always a good idea), then you should redirect the event and errors to tables in the schema that owns the context.
These are the actions that you must take to enable per-context logging for your application:
/servicelogs
context of the service root, using the accesslog
tool.
Use the session shell bind
command to bind the event and error handling capability into the /servicelogs
context of the service. Indicate the names of the tables that you created in the step above to set an attribute for the bound classes. Here are examples based on the HRService
:
bind /HRRoot/servicelogs/event -rebind \ -c SYS:oracle.aurora.namespace.rdbms.TableStream \ -f oracle.aurora.namespace.PublishedObjectFactory \ -string table.name HR.EVENT$LOG bind /HRRoot/servicelogs/error -rebind \ -c SYS:oracle.aurora.namespace.rdbms.TableStream \ -f oracle.aurora.namespace.PublishedObjectFactory \ -string table.name HR.ERROR$LOG
The names used below are for the tables created for the HRRoot
demos. You may use any names for your application. There are three tables:
<schema_name>.HTTP$LOG$
<schema_name>.EVENT$LOG
<schema_name>.ERROR$LOG
The HTTP log table has the same structure as SYS.JAVA$HTTP$LOG$
. Here is its description, as produced by SQL*Plus:
Column Name Type ------------------------------ ---- SERVER_NAME VARCHAR2(80) TIMESTAMP DATE REMOTE_HOST RAW(4) REMOTE_USER VARCHAR2(80) REQUEST_LINE VARCHAR2(256) STATUS NUMBER(3) RESPONSE_SIZE NUMBER(38) REQUEST_METHOD RAW(1) REFERER VARCHAR2(80) AGENT VARCHAR2(80)
The description of the EVENT$LOG table is:
Column Name Type ------------------------------ ---- ID NUMBER LINE NUMBER TEXT VARCHAR2(4000)
And here is the ERROR$LOG table:
Column Name Type ------------------------------ ---- ID NUMBER LINE NUMBER TEXT VARCHAR2(4000)
You must also create sequence numbers for use by the event and error logging. The following SQL commands create the required sequences. These are for the HR schema, substitute your own schema name and sequence names, as required:
create sequence HR.EVENT$LOG_ID create sequence HR.ERROR$LOG_ID
Oracle supplies example servlets that you can use or adopt to view the log tables. They are the HttpRdbmsLogServlet and the TableReaderServlet classes. You can use the following session shell commands to publish these servlets into your context. Use the table names that you employed in the CREATE TABLE
commands to set the table.name
property for the published names.
$ publishservlet -virtualpath /http_log HRContext httpLog_viewer \
SYS:oracle.aurora.mts.http.servlet.HttpRdbmsLogServlet -properties \
table.name=HR.HTTP$LOG$ $ $ publishservlet -virtualpath /error_log HRContext error_log_viewer \
SYS:oracle.aurora.mts.http.servlet.TableReaderServlet -properties \
table.name=HR.ERROR$LOG $ $ publishservlet -virtualpath /event_log HRContext event_log_viewer \
SYS:oracle.aurora.mts.http.servlet.TableReaderServlet -properties \
table.name=HR.EVENT$LOG
The timeout values determine how long a stateful session will stay active after the last request. There are two timeout properties for the service. In addition, each servlet context can establish its own timeout value, which takes precedence over the global service and endpoint timeouts. Also, individual servlets can set a timeout value for the session, using the setMaxInactiveInterval()
method of the HttpSession
interface.
This is a property of the service
group for the service. This value defaults to 60 seconds when a service is created. You can change the default using the createservice
command when you create the service, but you cannot change it if using the createwebservice
command.
You can see the value of the global timeout by entering these commands in the session shell:
$ cd /service
$ getgroup <service_name> service
You can also change the global timeout using the addgroupentry
command, after the service has been
created. Specify the new value in seconds.
Each service endpoint can have a separate timeout value, less than or equal to the global session service timeout. You can set the timeout for each endpoint when the endpoint is established, using the -timeout
option of the addendpoint
command (value in milliseconds). You can see the timeout values for all endpoints by using these session shell commands:
$ cd /service $ getgroup <service_name> endpoint
Each servlet context can have a default timeout, which applies to all servlets in the context that have not set their own timeout values. The servlet context default timeout is set in the config
object of the servlet context. (The config
object for the servlet context is in the root directory of the context.)
This timeout is set in the context.properties
group of the config
object, as the property context.default.timeout
. Set it using the addgroupentry
command, as follows (using the HR demo context as the example):
$ cd /HRRoot/contexts/HRContext $ addgroupentry config context.properties context.default.timeout NN
where NN is the timeout value in seconds.
Use the publishservlet
session shell command to publish servlets. The syntax of this command is:
publishservlet [options] <context_name> <servlet_name> <class_name
where the options are:
[-virtualpath <path>]
[-stateless]
[-reuse]
[-properties props]
The command parameters are:
The publishservlet
command does two things:
named_servlets
directory (context) of the servlet context.
named_servlets
directory.
The JNDI object that is bound into the named_servlets
directory contains the servlet class name and any initialization parameters for the servlet, as specified in the -properties
option of the publishservlet
command. You can see the class name and other properties of a published servlet by using the getproperties
session shell command on the published object.
This section reviews and summarizes information that has been presented in previous sections. It presents a complete scenario, in which the following steps are performed:
Where it is useful, the results of a step are examined. For example, after many steps that use session shell commands, the ls
and getproperties
commands are used to examine the results of the step. SQL*Plus is also used to show the results when objects are added to the database. If you follow each step in this Summary, you should have a better understanding of how to use the Oracle Servlet Engine to develop servlet-based applications.
Throughout this section, as in the remainder of this guide, we use the following notational conventions:
%
indicates an operating system prompt. Do not enter the '%'.
$
indicates a session shell prompt. Do not enter it.
SQL>
is a SQL*Plus command prompt.
Remember that each of the commands used is also documented in earlier sections of this chapter and in the Oracle9i Java Tools Reference.
This step creates a Web service that supports a single Web domain. The service is called the testService
, and is created to be used by the familiar schema HR
.
To start off, enter the session shell as the SYS user:
% sess_sh -user SYS -password change_on_install -role SYSDBA -service \
http://localhost:8080
Once in the session shell, list the contents of the root directory of the JNDI namespace:
$ ls /
In a newly installed Oracle platform, you should see something like this:
bin/ HRRoot/ system/ etc/ service/ test/
Some of these "directories" (or JNDI contexts) might be absent, depending on your installation. But the bin
, etc
, service
and system
entries must be there. HRRoot
is the root of the HRService
--a service and Web domain that supports the demonstration servlets that are installed with Oracle9i.
Create the Web service:
$ createwebservice -root /testRoot testService $ ls bin/ service/ etc/ system/ testRoot/
Verify that the service object was created in the /service
context:
$ ls /service admin testService HRService
Yes, it's there. Now add one endpoint to the service:
$ addendpoint -port 8088 -register testService testEndPoint
Look at the testService
object in the /service
context. What does it contain?
$ getproperties /service/testService --group--=service service.name=Service testService service.description=Aurora HTTP Servlet Engine service.version=1.0 service.vendor=Oracle Corp. service.globalTimeout=60 service.root=/testRoot service.presentation=http://testService service.error.log=servicelogs/error service.event.log=servicelogs/event --group--=endpoint endpoint.class=SYS:oracle.aurora.mts.ServiceEndpoint endpoint.name=testEndPoint endpoint.testEndPoint.interface=* endpoint.testEndPoint.port=8088 endpoint.testEndPoint.backlog=50 endpoint.testEndPoint.min.threads=3 endpoint.testEndPoint.max.threads=5 endpoint.testEndPoint.timeout=30000 --group--=environment --group--=contexts --group--=mime java=text/plain html=text/html ...
Most of the properties under the group service
are default values for the createwebservice
command. Likewise the properties in the group endpoint
are defaults added by the addendpoint
command. Only service name and the endpoint port number are not defaults.
It is important to now make the schema HR the owner of the objects in the service. Not doing so would open a big security hole in the server.
$ chown -R HR /testRoot
Verify the ownership:
$ ls -l /testRoot Read Write Exec Owner Date Time Type Name SYS SYS SYS HR Feb 24 12:02 Context servicelogs
Note that SYS remains the owner of the service object:
$ ls -l /service/testService Read Write Exec Owner Date Time Type Name SYS SYS SYS SYS Feb 24 12:02 Service service/testService
This is normal, and is fact is required. You now have a working Web service, that supports a single Web domain.
The Web domain is created in the testRoot
service, and has that name. Because this is a single-domain Web service, the name of the Web domain is arbitrary. When you create a Web domain, you also specify the default document root for the domain. You specify a directory on a file system of the host machine. You can put a welcome.html
file in there to be served as the default page for the domain. (The file names and locations are arbitrary--you do not have to imitate the ones shown here.)
Before creating the Web domain, have a look at the service root:
$ cd $ ls testRoot servicelogs/
Note that the only object there is the servicelogs
context. This is created by the createwebservice
command. Now reconnect to the session shell as the HR user, and create the Web domain. First exit from the session shell, then restart it as the HR user:
$ exit % % sess_sh -user HR -password hr -service http://localhost:8080 $ createwebdomain -docroot /tmp/testDomain /testRoot
Look again at the /testRoot
context:
$ ls /testRoot config contexts/ logs/ servicelogs/
The createwebdomain
command created a contexts
"context", a logs
context, and a config
object in the root of the Web domain. What does the config
object contain? Look at it:
$ cd /testRoot $ getproperties config --group--=environment --group--=contexts --group--=mime java=text/plain html=text/html htm=text/html body=text/html xml=application/xml ... # (and so on)
Not too much of interest here yet. We will come back to this config
object later.
This is a very important step. For clients to access the files in the document root, you must set the Java permissions on these files so that users can access them.
You must first connect to the database as a user who has permissions to grant Java file access permissions to the required users. In this example we connect as the SYS user, but you can use any database user who has the right grant capability.
% sqlplus 'SYS/change_on_install as SYSDBA'
SQL> call dbms_java.grant_permission('HR', 'java.io.FilePermission',
'/tmp/testDomain/*
', 'read,write');
SQL> Call completed.
SQL> exit
The OS directory does not have to exist when you grant these permissions. See the Security chapter of the Oracle9i Java Developer's Guide for more information about file permissions.
Load an HTML page into the document root, using OS commands. Here is an example welcome page that you can use:
<html> <head> <meta http-equiv="Content-Language" content="en-us"> <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> <title>Welcome to the Test Context</title> </head> <body> <h1 align="center"><b>Welcome to the Test Context</b></h1> <p>This page is located in the doc root of the <i>test</i> context</p> <p>The servlet context testContext is located at <a href="/ose/">/ose</a> </body> </html>
When you create a Web service, you should bind the classes that perform the event and error logging into the service. See "System Classes". Use these commands while connected to the session shell as SYS:
bind /testRoot/servicelogs/event -rebind \ -c SYS:oracle.aurora.namespace.rdbms.TableStream \ -f oracle.aurora.namespace.PublishedObjectFactory \ -string table.name HR.EVENT$LOG bind /testRoot/servicelogs/error -rebind \ -c SYS:oracle.aurora.namespace.rdbms.TableStream \ -f oracle.aurora.namespace.PublishedObjectFactory \ -string table.name HR.ERROR$LOG
Connect to the session shell as the HR user, if you are not already there:
% sess_sh -user HR -password hr -service http://localhost:8080 $ $ createcontext -virtualpath /ose -docroot /tmp/testDomain
/testRoot testContext
This section contains the code for an example servlet that you can use. The servlet accesses the HR.EMPLOYEES table in the database, which is part of the HR sample schema.
The servlet code uses JDBC statements to query the database. Note that the server-side internal driver (KPRB driver) is used. See the Oracle9i JDBC Developer's Guide and Reference for more information about this driver.
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.sql.*; import oracle.jdbc.*; public class simpleHRServlet extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter out = new PrintWriter(resp.getOutputStream()); Connection conn = null; try { // connect with the server-side internal driver OracleDriver ora = new OracleDriver(); conn = ora.defaultConnection(); if (conn != null) { Statement stmt = conn.createStatement(); ResultSet rset = stmt.executeQuery("select EMPLOYEE_ID, LAST_NAME, HIRE_DATE from
HR.EMPLOYEES order by HIRE_DATE"); resp.setContentType("text/html"); out.println("<html><head><title>Servlet JDBC Example</title></head><body>"); out.println("<table border=3 cellspacing=2 cellpadding=4 bgcolor=#FFFFE7>"); out.println("<tr><td>Employee Number<td>Last Name<td>Date Hired"); int counter = 0; while (rset.next()) { out.println("<tr><td>" + rset.getInt(1) + "<td>" + rset.getString(2) + "<td>" +
rset.getDate(3)); counter++; } out.println("</table><br>"); out.println("A total of "+ counter + " records"); out.println("</body></html>"); rset.close(); stmt.close(); conn.close(); } } catch (java.sql.SQLException e) { e.printStackTrace(out); } out.flush(); out.close(); } public void init(ServletConfig cfg) throws ServletException { super.init(cfg); } public void destroy() { super.destroy(); } public String getServletInfo() { return "A simple JDBC servlet"; } }
Use a Java compiler compliant with JDK 1.2 to compile the source on the client. Make sure that servlet.jar
, dt.jar
, tools.jar
, and Oracle's classes12.zip
are all on the classpath when you compile. Here is a Solaris example, but you might need to modify this for your Oracle installation:
% javac -g -classpath .:$ORACLE_HOME/lib/servlet.jar:$ORACLE_ HOME/jdbc/lib/classes12.zip:$ORACLE_ HOME/sqlj/lib/translator.zip:/usr/local/jdk1.2.2/lib/dt.jar:/usr/local/jdk1.2.2/ lib/tools.jar simpleHRServlet.java
Use the loadjava
command to load the compiled class simpleHRServlet.class
into the database, as follows:
% loadjava -verbose -oracleresolver -resolve -oci8 -user HR \
-password hr simpleHRServlet.class
Use the session shell to publish the servlet to the OSE/OJVM, as follows:
% $ORACLE_HOME/bin/sess_sh -user HR/hr -service http://localhost:8080
-command "publishservlet -virtualpath /simpleServlet
/HRRoot/contexts/HRContext simpleHRServlet HR:simpleHRServlet"
Note that the virtual path /simpleServlet
was assigned to the class simpleHRServlet
in the command part of the session shell invocation.
We can now combine all the elements that we created in the previous sections to derive the complete URL that is needed to access the simpleHRservlet
. They are shown in Figure 3-1:
Use a Web browser to access the servlet, entering the URL shown in Figure 3-1.
In the examples in this section, we have set up an endpoint for the Oracle listener, and the URL here assumes a direct connection to the Oracle listener and dispatcher. In your applications use Apache/mod_ose
to access servlets. In that case, use the Apache listener port instead of 8088. If Apache is running, and mod_ose
has been configured correctly, with a /ose/
Location
directive, the rest of the URL can serve as is.
Each Web domain requires tables in the database that hold event and error logging information. Create these using SQL*Plus or another Oracle administrative tool. See "Logging" for more information.
-- The HTTP log table: create table HR.HTTP$LOG$ ( server_name VARCHAR2(80), timestamp DATE, remote_host RAW(4), remote_user VARCHAR2(80), request_line VARCHAR2(256), status NUMBER(3), response_size INTEGER, request_method RAW(1), referer VARCHAR2(80), agent VARCHAR2(80)) / -- Here's where the event log is stored: create table HR.EVENT$LOG ( id number, line number, text varchar2(4000) ) / -- The event logging sequence: create sequence HR.EVENT$LOG_ID / -- Here's where we store the error log create table HR.ERROR$LOG ( id number, line number, text varchar2(4000) ) / -- The sequence for controlling ordering in the error log table create sequence HR.ERROR$LOG_ID / -- don't forget to commit, if auto commit is not on commit;
Execute these statements using SQL*Plus or an Oracle database management tool.
In the simple example in this Summary section, we have said little about security. We did make sure that the JNDI objects published under the testService
root were not owned by SYS, and we did make sure that the static HTML files under the doc root were accessible by at least the HR user.
But if you are using this simple scenario as a basis for a real Web application, you must make sure that you properly address client authentication and authorization issues. See Chapter 7, "Oracle Servlet Engine Security", in this guide. If you are using Oracle Single Sign-On, you should also refer to the documentation about mod_osso
in "Using mod_osso with mod_ose".
|
Copyright © 1996-2001, Oracle Corporation. All Rights Reserved. |
|