Invoking Webservice from PL/SQL (UTL_DBWS&UTL_HTTP)

本文介绍了Oracle数据库中通过UTL_HTTP和UTL_DBWS两种方式调用外部Webservice的方法,并对比了它们各自的优缺点。提供了具体的示例代码,有助于理解如何在实际应用中使用这两种方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自:http://blog.youkuaiyun.com/pan_tian/article/details/25420947

从PL/SQL,Oracle提供了两种方式调用外部Webservice:一种是UTL_HTTP,另外一种是UTL_DBWS。
  • utl_http – low level http assembler
  • utl_dbws – high level web service package

UTL_HTTP

•Available as of 8.0.5
•Send/receive raw HTTP request/responses to external servers
•Advantages:
Simplistic
–Installed (completely) in the database
–Passed and returns a VARCHAR2 XML payload
–Very easy if you know the XML payload structures
–Doesn't require a WSDL at publisher's site
–Good examples available on the internet
–3 rdparty PL/SQL wrappers available (Tim Hall:  soap_api)
•Disadvantages:
–Low level with no smarts to support web services
–Cryptic HTTP error messages
Oracle documentation is less than useful

UTL_DBWS

  • Available as of 10gR1
  • PL/SQL Java wrapper on oracle.jpub.runtime.dbws.DbwsProxy
  • Part of JPublisher
  • Advantages:
                    - High(er) level web service handler

  • Disadvantages:
-Not completely installed by default (bah!)
-Poor error reporting (in particular HTTP)
-Queries external WSDL each request
-Oracle documentation is dismal
-Use of HttpUriType does not support wallets or proxies
-Minor bugs in 10gR2 version with external authentication
-Minor issues on calling .Net web services
-Uses database JVM

UTL_HTTP现在已经逐步取代UTL_DBWS。

UTL_HTTP Sample


DECLARE
  L_PARAM_LIST VARCHAR2(512);

  L_HTTP_REQUEST  UTL_HTTP.REQ;
  L_HTTP_RESPONSE UTL_HTTP.RESP;

  L_RESPONSE_TEXT VARCHAR2(32767);
BEGIN

  -- service's input parameters
  L_PARAM_LIST := 'FromCurrency=EUR&ToCurrency=USD';

  -- preparing Request...
  L_HTTP_REQUEST := UTL_HTTP.BEGIN_REQUEST('http://www.webservicex.net/currencyconvertor.asmx/ConversionRate',
                                           'POST',
                                           'HTTP/1.1');

  -- ...set header's attributes
  UTL_HTTP.SET_HEADER(L_HTTP_REQUEST,
                      'Content-Type',
                      'application/x-www-form-urlencoded');
  UTL_HTTP.SET_HEADER(L_HTTP_REQUEST,
                      'Content-Length',
                      LENGTH(L_PARAM_LIST));

  -- ...set input parameters
  UTL_HTTP.WRITE_TEXT(L_HTTP_REQUEST, L_PARAM_LIST);

  -- get Response and obtain received value
  L_HTTP_RESPONSE := UTL_HTTP.GET_RESPONSE(L_HTTP_REQUEST);

  UTL_HTTP.READ_TEXT(L_HTTP_RESPONSE, L_RESPONSE_TEXT);

  DBMS_OUTPUT.PUT_LINE(L_RESPONSE_TEXT);

  -- finalizing
  UTL_HTTP.END_RESPONSE(L_HTTP_RESPONSE);

EXCEPTION
  WHEN UTL_HTTP.END_OF_BODY THEN
    UTL_HTTP.END_RESPONSE(L_HTTP_RESPONSE);
END;

UTL_DBWS Sample

 DECLARE
   v_namespace        VARCHAR2(1000) := 'http://www.sagecomputing.com.au/emp';
   v_service_qname    utl_dbws.qname := utl_dbws.to_qname(v_namespace,'employees');
   v_port_qname       utl_dbws.qname := utl_dbws.to_qname(v_namespace,'employeesSoapHttpPort');
   v_operation_qname  utl_dbws.qname := utl_dbws.to_qname(v_namespace,'getName');

   v_service           utl_dbws.service;
   v_call              utl_dbws.call;

   v_int_type          utl_dbws.qname;
   v_string_type       utl_dbws.qname;

   v_request_params    utl_dbws.anydata_list; -- RPC style only
   v_response_anydata  AnyData;               -- RPC style only

   v_request_xmltype   XmlType;               -- Document style only
   v_response_xmltype  XmlType;               -- Document style only   

BEGIN
   v_service := utl_dbws.create_service(
     HttpUriType('http://www.sage.com.au/employees?wsdl'), v_service_qname);

   v_call := utl_dbws.create_call(v_service, v_port_qname, v_operation_qname);

   utl_dbws.set_property(v_call, 'SOAPACTION_USE',    'TRUE');
   utl_dbws.set_property(v_call, 'SOAPACTION_URI',    'getName');
   utl_dbws.set_property(v_call, 'ENCODINGSTYLE_URI',
    'http://schemas.xmlsoap.org/soap/encoding/');  
   utl_dbws.set_property(v_call, 'OPERATION_STYLE',   'rpc');

   utl_dbws.set_property(v_call, 'OPERATION_STYLE',   'document');
   utl_dbws.set_property(v_call, 'OPERATION_STYLE',   'rpc');

   v_int_type    := utl_dbws.to_qname('http://www.w3.org/2001/XMLSchema', 'int');
   v_string_type := utl_dbws.to_qname('http://www.w3.org/2001/XMLSchema', 'string');

   utl_dbws.add_parameter(v_call, 'employeeNumber', v_int_type,    'ParameterMode.IN');
   utl_dbws.add_parameter(v_call, 'nameCase',       v_string_type, 'ParameterMode.IN');
   utl_dbws.set_return_type(v_call, v_string_type);  

   v_request_params(0) := AnyData.convertNumber(1234);
   v_request_params(1) := AnyData.convertVarchar('M');

   v_response_anydata := utl_dbws.invoke(v_call, v_request_params);
   dbms_output.put_line('Result = ' || v_response_anydata.accessVarchar2);

   utl_dbws.release_call(v_call);
   utl_dbws.release_service(v_service);
END;
/
Result = Christopher Muir



root@ecm-e00f:/# cat /etc/apparmor.d/usr.bin.man # vim:syntax=apparmor #include <tunables/global> /usr/bin/man { #include <abstractions/base> # Use a special profile when man calls anything groff-related. We only # include the programs that actually parse input data in a non-trivial # way, not wrappers such as groff and nroff, since the latter would need a # broader profile. /usr/bin/eqn rmCx -> &man_groff, /usr/bin/grap rmCx -> &man_groff, /usr/bin/pic rmCx -> &man_groff, /usr/bin/preconv rmCx -> &man_groff, /usr/bin/refer rmCx -> &man_groff, /usr/bin/tbl rmCx -> &man_groff, /usr/bin/troff rmCx -> &man_groff, /usr/bin/vgrind rmCx -> &man_groff, # Similarly, use a special profile when man calls decompressors and other # simple filters. /{,usr/}bin/bzip2 rmCx -> &man_filter, /{,usr/}bin/gzip rmCx -> &man_filter, /usr/bin/col rmCx -> &man_filter, /usr/bin/compress rmCx -> &man_filter, /usr/bin/iconv rmCx -> &man_filter, /usr/bin/lzip.lzip rmCx -> &man_filter, /usr/bin/tr rmCx -> &man_filter, /usr/bin/xz rmCx -> &man_filter, # Allow basically anything in terms of file system access, subject to DAC. # The purpose of this profile isn't to confine man itself (that might be # nice in the future, but is tricky since it's quite configurable), but to # confine the processes it calls that parse untrusted data. /** mrixwlk, unix, capability setuid, capability setgid, # Ordinary permission checks sometimes involve checking whether the # process has this capability, which can produce audit log messages. # Silence them. deny capability dac_override, deny capability dac_read_search, signal peer=@{profile_name}, signal peer=/usr/bin/man//&man_groff, signal peer=/usr/bin/man//&man_filter, # Site-specific additions and overrides. See local/README for details. #include <local/usr.bin.man> } profile man_groff { #include <abstractions/base> # Recent kernels revalidate open FDs, and there are often some still # open on TTYs. This is temporary until man learns to close irrelevant # open FDs before execve. #include <abstractions/consoles> # man always runs its groff pipeline with the input file open on stdin, # so we can skip <abstractions/user-manpages>. /usr/bin/eqn rm, /usr/bin/grap rm, /usr/bin/pic rm, /usr/bin/preconv rm, /usr/bin/refer rm, /usr/bin/tbl rm, /usr/bin/troff rm, /usr/bin/vgrind rm, /etc/groff/** r, /etc/papersize r, /usr/lib/groff/site-tmac/** r, /usr/share/groff/** r, /tmp/groff* rw, signal peer=/usr/bin/man, # @{profile_name} doesn't seem to work here. signal peer=/usr/bin/man//&man_groff, } profile man_filter { #include <abstractions/base> # Recent kernels revalidate open FDs, and there are often some still # open on TTYs. This is temporary until man learns to close irrelevant # open FDs before execve. #include <abstractions/consoles> /{,usr/}bin/bzip2 rm, /{,usr/}bin/gzip rm, /usr/bin/col rm, /usr/bin/compress rm, /usr/bin/iconv rm, /usr/bin/lzip.lzip rm, /usr/bin/tr rm, /usr/bin/xz rm, # Manual pages can be more or less anywhere, especially with "man -l", and # there's no harm in allowing wide read access here since the worst it can # do is feed data to the invoking man process. /** r, # Allow writing cat pages. /var/cache/man/** w, signal peer=/usr/bin/man, # @{profile_name} doesn't seem to work here. signal peer=/usr/bin/man//&man_filter, }
最新发布
06-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值