首先,轻描淡写的解释一下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;