您的位置:首页 > 数据库 > Oracle

oracle plsql调用webservice

2012-11-25 16:45 134 查看
        首先,轻描淡写的解释一下webservice,个人理解,webservice的出现并不是必须的,只是因为各个平台在设计之初只考虑自己的事情,不关注其他周围的可能会发生的事情,当然这种情况的发生和技术,历史有关,现在不是搞云计算了么。。。也许以后就不会用webservice这样的东西了。当然,万事都需要有时间阶段,现在还是有必要掌握,毕竟它是业界交换数据的一种标准。关于webservice还有很多,在这就不空谈阔论了!

      在这,就简单的介绍plsql调用webservice,plsql调用webservice有两种方式:utl_dbws和utl_http的方式,前一个方法需要插件支持,本人没有尝试过,后一种方法是以http请求的方式,属于轻量级的,这里就简单介绍后一种。通常别人发布好webservice的时候会生成一个wsdl文件,然后他们会把文件告诉我们,我们通过这文件就会知道我们需要调用的:地址,函数,参数,返回值等,如果是通过Java开发,通常像eclipse等开发工具通过这文件就会自动生成相应的对象,我们只要调用就可以,后面的工作会由工具来做。但是plsql由于是过程型语言,也就是属于比较底层,就意味着凡事都得自己来做,所以呢我们首先需要看得懂wsdl文件,根据看懂的内容得到请求的xml,当然有一些工具可以使用,比如soapui,就很好用。就这样我们根据wsdl获取了我们需要的请求地址和请求的xml,接下来就是如果调用了。

   下面是调用的详细步骤和说明:

  

1.  设置请求的URL,即请求的webservice地址,如:http://10.16.30.*:8080/fbfound/services/QueryService

2.      设置soap请求的头和尾,因为utl_http是以application/soap+xml的方式请求webservice所以需要按照SOAP协议的格式设置头尾信息,如:

v_phead  VARCHAR2(1000)
:='<soapenv:Envelopexmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Body>';
v_pend VARCHAR2(1000)
:='</soapenv:Body></soapenv:Envelope>';

3.      设置其他变量,如缓冲区,缓冲大小等,具体看附件程序

4.      把请求的xml文件的文件转换为字符串(clob类型)

5.      发动http连接,l_http_request:=UTL_HTTP.begin_request

6.      设置请头信息:

utl_http.set_transfer_timeout(timeout=>
1000);

  utl_http.set_body_charset(l_http_request,
'utf-8');

  utl_http.set_header(l_http_request,
                    
'Content-Type',

                     'application/soap+xml;charset=utf-8');

utl_http.set_header(l_http_request,
'Content-Length', v_length);--必须设置,不然会报EOF异常,长度为内容加头尾

utl_http.set_header(v_http_req,
'SOAPAction',
'×××');(如果wsdl有描述则需要加此头)

7.      把soap头写入http请求。

8.      根据设置的缓冲区循环把请求的内容写入http请求。

9.      把soap尾写入http请求

10.  获取响应UTL_HTTP.get_response(l_http_request)

11.  把响应的报文按缓冲设置循环写入相应的clob

12.  捕获utl_http.end_of_body异常,如果不处理则在读取完成之后会抛异常。

把响应的报文转换为xml格式文档

以上便是完整的流程,当然如果你使用的是oracle119会报ACL访问控制列表错误,这时你需要做如下操作:

创建ACL

用具有管理员权限的用户进入数据库,执行以下脚本创建ACL。

BEGIN
 DBMS_NETWORK_ACL_ADMIN.create_acl (
   acl          =>'test_acl_file.xml', --控制的xml
   description  => 'A test of theACL functionality',
   principal    => 'TEST1',--用户
   is_grant     => TRUE, --是否可以访问
   privilege    => 'connect',--设置权限
   start_date   => SYSTIMESTAMP,
   end_date     => NULL);
 
 COMMIT;
END;
/

ACL分配网络

                       ACL分配网络,执行以下脚本分配网络。

BEGIN

  DBMS_NETWORK_ACL_ADMIN.assign_acl (

    acl         => 'test_acl_file.xml',

    host        => '192.168.2.3', --acl可以访问的网络

    lower_port  => 80,

    upper_port  => NULL);

  COMMIT;

END;

/


  查看ACL

                       如果访问的网络数量比较多,可以执行以下脚本,就可以访问所有网络。

CONN / AS SYSDBA

BEGIN

  DBMS_NETWORK_ACL_ADMIN.create_acl (

    acl          => 'open_acl_file.xml',

    description  => 'A test of the ACL functionality',

    principal    => 'TEST',

    is_grant     => TRUE,

    privilege    => 'connect',

    start_date   => SYSTIMESTAMP,

    end_date     => NULL);

 

  DBMS_NETWORK_ACL_ADMIN.assign_acl (

    acl         => 'open_acl_file.xml',

    host        => '*',

    lower_port  => 1,

    upper_port  => 9999);

 

  COMMIT;

END;

/


                                    建好ACL和分配网络后可以通过下面的方式查看。

SELECT acl,

       principal,

       privilege,

       is_grant,

       TO_CHAR(start_date, 'DD-MON-YYYY') AS start_date,

       TO_CHAR(end_date, 'DD-MON-YYYY') AS end_date

FROM   dba_network_acl_privileges;

 

SELECT host, lower_port, upper_port, privilege, status

FROM   user_network_acl_privileges;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: