最近涉及到系统改造,系统内一些存储过程不能再继续使用,改为供应商提供http接口,为了尽可能少改动系统,故利用oracle提供的utl_http包完成对供应商http的访问获取所需数据。
一、Oracle 创建ACL进行http请求
Oracle(11g及以上版本)进行http请求,需要先创建ACL权限(在管理员账号下创建)
begin
dbms_network_acl_admin.create_acl (
acl => 'utl_http.xml',
description => 'HTTP Access',
principal => 'DBUSER',
is_grant => TRUE,
privilege => 'connect',
start_date => NULL,
end_date => NULL
);
dbms_network_acl_admin.add_privilege (
acl => 'utl_http.xml',
principal => 'DBUSER',
is_grant => TRUE,
privilege => 'resolve',
start_date => NULL,
end_date => NULL
);
dbms_network_acl_admin.assign_acl (
acl => 'utl_http.xml',
host => '10.78.236.127',
lower_port => 0,
upper_port => 30000
);
commit;
end;
检查是否赋权成功,若查询到刚才操作的相关数据则表示赋权成功,即可使用utl_http包访问webapi了。
SELECT * FROM dba_network_acls
SELECT * FROM dba_network_acl_privileges
二、利用UTL_HTTP包编写网络请求函数
GET
CREATE OR REPLACE FUNCTION HTTP_GET (v_url VARCHAR2)
RETURN VARCHAR2
AS
BEGIN
DECLARE
req UTL_HTTP.REQ;
resp UTL_HTTP.RESP;
v_line VARCHAR2 ( 4000 );
v_text VARCHAR2 ( 4000 );
BEGIN
v_text := '';
BEGIN
req := UTL_HTTP.BEGIN_REQUEST ( url => v_url, method => 'GET' );
UTL_HTTP.SET_BODY_CHARSET('UTF-8');
UTL_HTTP.SET_HEADER(req, 'Content-Type', 'application/x-www-form-urlencoded');
resp := UTL_HTTP.GET_RESPONSE ( req );
LOOP
UTL_HTTP.READ_LINE ( resp, v_line, TRUE );
v_text := v_text || v_line;
END LOOP;
UTL_HTTP.END_RESPONSE( resp );
UTL_HTTP.END_REQUEST( req );
EXCEPTION
WHEN UTL_HTTP.END_OF_BODY THEN
UTL_HTTP.END_RESPONSE ( resp );
WHEN OTHERS THEN
UTL_HTTP.END_RESPONSE(resp);
UTL_HTTP.END_REQUEST(req);
END;
return v_text;
END;
END;
POST
CREATE OR REPLACE FUNCTION HTTP_POST (v_url VARCHAR2, v_body VARCHAR2, v_body_type VARCHAR2)
RETURN VARCHAR2
AS
BEGIN
DECLARE
req UTL_HTTP.REQ;
resp UTL_HTTP.RESP;
v_line VARCHAR2 ( 4000 );
v_text VARCHAR2 ( 4000 );
BEGIN
v_text := '';
BEGIN
req := UTL_HTTP.BEGIN_REQUEST ( url => v_url, method => 'POST' );
UTL_HTTP.SET_BODY_CHARSET('UTF-8');
UTL_HTTP.SET_HEADER(req, 'Content-Type', v_body_type);
utl_http.set_header(req, 'Content-Length',lengthb(v_body));
utl_http.write_text(req, v_body);
resp := UTL_HTTP.GET_RESPONSE ( req );
LOOP
UTL_HTTP.READ_LINE ( resp, v_line, TRUE );
v_text := v_text || v_line;
END LOOP;
UTL_HTTP.END_RESPONSE( resp );
UTL_HTTP.END_REQUEST( req );
EXCEPTION
WHEN UTL_HTTP.END_OF_BODY THEN
UTL_HTTP.END_RESPONSE ( resp );
WHEN OTHERS THEN
UTL_HTTP.END_RESPONSE(resp);
UTL_HTTP.END_REQUEST(req);
END;
return v_text;
END;
END;
三、编写RESTAPI测试
使用SpringBoot快速创建四个接口用于请求测试。
@GetMapping("testGet")
@ResponseBody
public String testGet(){
return "testGet";
}
@GetMapping("testGetParam")
@ResponseBody
public String testGetParam(HttpServletRequest request){
String param = request.getParameter("aac001");
log.info("aac001:"+param);
return "testGetParam";
}
@PostMapping("testPost")
@ResponseBody
public String testPost(){
return "testPost";
}
@PostMapping("testPostParam")
@ResponseBody
public String testPostParam(HttpServletRequest request){
String aac001 = request.getParameter("aac001");
String aab001 = request.getParameter("aab001");
log.info("aac001:"+aac001);
log.info("aab001:"+aab001);
return "testPost";
}
不带参数的GET请求 不带参数的POST请求 带参数的GET请求 带参数的POST请求 WEB后台打印的数据 至此,Oracle访问Web RESTAPI的过程结束。
参考链接:Oracle 使用UTL_HTTP发送http请求
|