使用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;
至此,訪問存儲過程或者觸發器,測試對應的程序即可。