You are on page 1of 5

Using UTL_DBWS to Make a Database 11g

Callout to a Document Style Web Service


原创 2014年11月09日 18:00:51

In this Document

Purpose
Scope
Details

APPLIES TO:

Oracle Database - Enterprise Edition - Version 11.1.0.6 and later


Web Services - Version 10.1.3.1.0 and later
Information in this document applies to any platform.

PURPOSE

This article provides a method for consuming a Document Style Web Service using the UTL_DBWS package
in the 11G version of the database. UTL_DBWS is a PL/SQL database package that contains a series of
commands that developers can use to create a runtime PL/SQL procedure or function that will allow
for the transfer of information from a web service to the database.

SCOPE

This article is intended for Web Service Developers.

DETAILS

The steps to be used are as follows:

1) Download the LATEST copy of the UTL_DBWS utility zip file from the Oracle Technology Network
(OTN). This file, for an 11G database, is named dbws-callout-utility-10131.zip and can be obtained
from here.

2) Extract the contents of the zip file to the $ORACLE_HOME directory. This will place the contents
of the zip in the $ORACLE_HOME/sqlj/lib directory.

3) The 11.1 version of the database contains the UTL_DBWS PL/SQL package in the SYS schema by
default, but the 11.2 version does not have this loaded automatically. If you are using the 11.2
version, you can run the appropriate PL/SQL package body and specification in order to install the
core PL/SQL code into whatever schema you wish to use. The code used for the example will assume
that the SYS schema was used, as per the default installation for the 11.1 version, but it is
possible to load this package into the same schema that is being used for the loadjava commands
performed in step 4 below. The packages to be loaded are named utl_dbws_body.sql and
utl_dbws_decl.sql and exist in the $ORACLE_HOME/sqlj/lib directory after the callout utility zip has
been unzipped into the $ORACLE_HOME directory. Once the package is in place, is important to
perform a couple of checks to ensure the database environment is ready for use with the callout
mechanism.

a) Make sure the initialization parameters SHARED_POOL_SIZE and JAVA_POOL_SIZE are equal to or
greater than 96M and 80M, i.e.,

shared_pool_size=96M
java_pool_size=80M

b) Check to ensure that the jvm objects in the SYS schema are valid. You can check this by logging
into the database as SYS and running the following query:

SELECT owner, status, count(*) FROM DBA_OBJECTS


WHERE OBJECT_TYPE='JAVA CLASS'
GROUP BY owner, status;

If there are classes that are listed as being in an 'INVALID' state, you can run the following
script to attempt to make these objects VALID:

$ORACLE_HOME/rdbms/admin/utlrp.sql

Once this has been run, recheck the status of your Java objects. If there are still any that are
INVALID, it may be necessary to contact Oracle Support to determine how to make these objects VALID
before continuing.

4) Load the necessary core web services callout jar files into the database. This step is to load
the core Java components and is a completely separate action from loading the PL/SQL package as
described in the previous steps. This means that the considerations for completing this step are
entirely different from the loading of the PL/SQL components. In the 11gR2 version of the
database, it has been determined that loading the jars into ths SYS schema will cause conflicts
with existing classes already loaded in this schema by default so a user created schema will need to
be used for loading of these jars (CONNECT, RESOURCE and CREATE PUBLIC SYNONYM are the minimum
grants that have to be performed on this schema). For 11.1.0.x, this Java loading restrication does
not exist, and it is possible to load the jars into the SYS scheama, although it is strongly
recommended that a user defined schema be created for the loading of the jars in this version as
well. By separating the loading of the callout classes into its own schema, even for the 11gR1
version, it should ensure that no conflicts will occur with classes that have been already loaded
into the database in other schemas, so it is good practice in all cases to create a user defined
schema for the loading of the jar files necessary for the use of the UTL_DBWS package.

When loading the jar files in the desired schema, make sure the PATH environment variable includes
the $ORACLE_HOME/bin directory. From a terminal window, run the following commands:

cd $ORACLE_HOME/sqlj/lib (replacing $ORACLE_HOME with the proper directory structure)


loadjava -u username/password -r -v -f -s -grant public -genmissing dbwsclientws.jar
dbwsclientdb11.jar

Replace the username/password designation with whatever applies in your particular database
environment.

5) There are a series of permission grants that must be performed. These grants only have to be
performed once before the functionality is available. From the SYS schema, run the following
commands:
execute
dbms_java.grant_permission('<SCHEMA>','SYS:java.util.PropertyPermission','http.proxySet','write');
execute dbms_java.grant_permission('<SCHEMA>','SYS:java.util.PropertyPermission','http.proxyHost',
'write');
execute dbms_java.grant_permission('<SCHEMA>','SYS:java.util.PropertyPermission','http.proxyPort',
'write');
execute dbms_java.grant_permission('<SCHEMA>','SYS:java.lang.RuntimePermission',
'accessClassInPackage.sun.util.calendar','');
execute
dbms_java.grant_permission('<SCHEMA>','SYS:java.lang.RuntimePermission','getClassLoader','');
execute
dbms_java.grant_permission('<SCHEMA>','SYS:java.net.SocketPermission','*','connect,resolve');
execute dbms_java.grant_permission('<SCHEMA>','SYS:java.util.PropertyPermission','*','read,write');
execute dbms_java.grant_permission('<SCHEMA>','SYS:java.lang.RuntimePermission','setFactory','');

The <SCHEMA> designation is to be replaced with the actual schema name being used. The name must
also be designated in caps.

If your environment does not use a proxy server, the first three dbms_java.grant_permission
statements listed do not need to be executed and can be ignored.

6) As a test, the following UTL_DBWS function can be used as a test to ensure the callout mechanism
is installed correctly. The function calls an external web service that converts Celsius
temperatures to Fahrenheit.

CREATE OR REPLACE FUNCTION celciusToFahrenheit(temperature


NUMBER) RETURN VARCHAR2 AS

service_ sys.utl_dbws.SERVICE;
call_ sys.utl_dbws.CALL;
service_qname sys.utl_dbws.QNAME;
port_qname sys.utl_dbws.QNAME;
response sys.XMLTYPE;
request sys.XMLTYPE;

BEGIN
sys.utl_dbws.set_http_proxy('myproxyserver:8080');
service_qname := sys.utl_dbws.to_qname(null,
'CelciusToFahrenheit');
service_ := sys.utl_dbws.create_service(service_qname);
call_ := sys.utl_dbws.create_call(service_);
sys.utl_dbws.set_target_endpoint_address(call_,
'http://webservices.daehosting.com/services/TemperatureConvers
ions.wso');
sys.utl_dbws.set_property( call_, 'OPERATION_STYLE',
'document');
request := sys.XMLTYPE('<CelciusToFahrenheit
xmlns="http://webservices.daehosting.com/temperature"><nCelciu
s>'||temperature||'</nCelcius></CelciusToFahrenheit>');
response :=sys.utl_dbws.invoke(call_, request);
return
response.extract('//CelciusToFahrenheitResult/child::text()',
'xmlns="http://webservices.daehosting.com/temperature"').getst
ringval();
END;
/

NOTE: The SYS prefix for the UTL_DBWS calls assumes that the PL/SQL package is loaded into SYS. If
this is not the case in the particular environment being used, and the package is loaded into
another schema, please make the adjustments necessary to the code to reflect the schema that holds
the UTL_DBWS package.

BACKGROUND OF CODE USED


------------------------

The sys.utl_dbws.set_http_proxy call is used take into account any proxy server that would exist in
the database environment. The value provided is an example of the syntax, and must be replaced with
the values that suit the database environment. This line of code can be removed entirely if no proxy
server exists in the environment.

The sys.utl_dbws.to_qname call provides a mechanism to provide the service and call name necessary
for the operations to be performed. Due to the simplicity of the web service being used for testing,
null is all that is necessary to provide for the service name. In a production environment, this
would likely be a particular value that would have to be determined and provided in place of null.
In this case, the operation name is CelciusToFarenheit. This value can be found by examining the
WSDL, and looking for the <operation> tag and determining the name parameter. For the example above,
the WSDL can be found at the following URL:

http://webservices.daehosting.com/services/TemperatureConversions.wso?WSDL

The request parameter is created as an XMLTYPE, as Document Style web services use xml parameters
both for input and output. It is necessary to determine what the web service is expecting to receive
in it's entirety as a request in order to supply the correct information to this parameter.
Determine the syntax contained in the <soap:Body> tag for the request envelope of the service to get
the value to be passed in the XMLTYPE variable. For the same reason, the response is an XMLTYPE as
well. This makes it simple to use the extract method of this type to get the result in a form that
can be used for whatever purposes desired..

The output below shows the function in action.

SQL> SELECT celciusToFahrenheit(30) from dual;

CELCIUSTOFAHRENHEIT(30)
--------------------------------------------------------------
----------------
86

SQL>

This example was built using a third-party web service. If you find in testing that this fails to
function, it may be due to the web service being taken offline. By executing the following URL in a
browser window:

http://webservices.daehosting.com/services/TemperatureConversions.wso

You should be able to determine if this is the case.

If you would prefer not to use UTL_DBWS for your web services callout, there is another approach can
be taken. This uses the JPublisher utility to create a Java Stored Procedure with a PL/SQL wrapper
that can be used to access the code. This approach is outline in the following note, available on
MetaLink:

Note 469588.1 - DBWS Callout Utilities User's Guide for RDBMS 11.1

For more information on making web service callouts from the database, see:

Callout Users Guide


UTL_DBWS Package Reference
Developing a Web Service Client in the Database

You might also like