oracle发送http请求。


使用oracle发送http请求,实现的思路是:在某张表上配置触发器,该触发器调用存储过程,使用存储过程执行http请求的发送。

需要注意的几点是:

1、http post请求,在发送的时候,跟数据库的字符集有关,在处理不当的时候,会出现乱码问题。

2、oracle访问网络服务的时候,需要配置acl权限。


创建触发器:

CREATE OR REPLACE TRIGGER "T_POST4REQHAND" AFTER INSERT ON "REQUESTHANDLERINFO" REFERENCING OLD AS "OLD" NEW AS "NEW" FOR EACH ROW 
declare
begin
   PRO_POSTREQ(:new.id,:new.params);  
end T_POST4REQHAND;

创建存储过程:

create or replace procedure "PRO_POSTREQ"(r_id in varchar2,params in varchar2) as
begin

DECLARE
  req   UTL_HTTP.REQ;
  resp  UTL_HTTP.RESP;
  value VARCHAR2(1024);  -- URL to post to
   v_url VARCHAR2(4000) := 'http://192.168.0.156:8080/bzjw_platform/f/responseresult/responseResult/invokeOutRequest?rid='||r_id||'&¶ms'||params;
   v_param VARCHAR2(4000) := '1';


  v_param_length NUMBER := LENGTHB(v_param);
BEGIN
   DBMS_OUTPUT.ENABLE (buffer_size=>null);
  req := UTL_HTTP.BEGIN_REQUEST (url=> v_url, method => 'POST');
  UTL_HTTP.SET_BODY_CHARSET('UTF-8');
  UTL_HTTP.SET_HEADER (r      =>  req,
                       name   =>  'Content-Type',
                       value  =>  'application/x-www-form-urlencoded');
  UTL_HTTP.SET_HEADER(req, 'Keep-Alive', '  timeout=1');
  UTL_HTTP.SET_HEADER (r      =>   req,
                       name   =>   'Content-Length',
                       value  =>   v_param_length);
 
   UTL_HTTP.WRITE_RAW (r    => req,
                    data => UTL_RAW.CAST_TO_RAW(v_param)); 

  resp := UTL_HTTP.GET_RESPONSE(req);
  LOOP
    UTL_HTTP.READ_LINE(resp, value, TRUE);
    DBMS_OUTPUT.PUT_LINE(value);
  END LOOP;
  UTL_HTTP.END_RESPONSE(resp);
EXCEPTION
  WHEN UTL_HTTP.END_OF_BODY THEN
    UTL_HTTP.END_RESPONSE(resp);
END;
end PRO_POSTREQ;



该请求为post,但是所有的参数传递均放置在URL中,原因是,放置在v_param 这个参数中时,数据库字符集为utf8的时候,一切正常,但是若是gbk,则发生乱码。

原因是 oracle的参数拼接字符 “||”会进行一次编码。 按照网上所说的,使用转码等一系列操作,最终仍没有解决。


定义ACL,若没有ACL,则无法访问网络。

--定义ACL 取名:httprequestpermission.xml

BEGIN
    dbms_network_acl_admin.create_acl(acl         => 'httprequestpermission.xml',
                                      DESCRIPTION => 'Normal Access',
                                      principal   => 'CONNECT',
                                      is_grant    => TRUE,
                                      PRIVILEGE   => 'connect',
                                      start_date  => NULL,
                                      end_date    => NULL);
END;
--查看ACL是否增加成功
SELECT any_path
FROM resource_view 
where any_path  like '/sys/acls/%.xml'
;

--给用户增加acl权限,这里是 SD_JY 注意是大写,小写不识别
begin  dbms_network_acl_admin.add_privilege(acl     => 'httprequestpermission.xml',
                                         principal  => 'SD_JY',
                                         is_grant   => TRUE,
                                         privilege  => 'connect',
                                         start_date => null,
                                         end_date   => null);
end;


--添加对应主机 ,将对应主机和端口添加到ACL。这里是 192.168.0.156 和 8080 ,这个ip和端口要和上面存储过程中定义的地址一致
begin
    dbms_network_acl_admin.assign_acl(acl        => 'httprequestpermission.xml',
                                      host       => '192.168.0.156',
                                      lower_port => 8080,
                                      upper_port => NULL);
end;

ACL的增加过程为:建立新的acl文件,对该文件中,用户授权,对该文件中,URL和端口授权。

可查看对应的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;


至此,访问存储过程或者触发器,测试对应的程序即可。



你可能感兴趣的:(Oracle)