【Oracle】调用HTTP接口

Oracle调用http接口

前情提要

公司唯有oracle被允许访问内外网,因此在oracle中发起HTTP请求。

1.创建HTTP请求函数

sql 复制代码
CREATE OR REPLACE FUNCTION HTTP_REQUEST(
  v_url  VARCHAR2,--請求地址
  v_param  VARCHAR2,--POST請求參數-->>'muser=32323&&passwd=232323';GET拼接URL
  v_type  varchar2--類型
  )return varchar2 is
  --GET--
   req UTL_HTTP.REQ;
   resp UTL_HTTP.RESP;
   v_line VARCHAR2 ( 4000 );
 v_text VARCHAR2 ( 4000 );
  v_param_length NUMBER ;
 --post--
 begin
     IF V_TYPE='GET' THEN  
           v_text := '';
           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/json');
           resp := UTL_HTTP.GET_RESPONSE ( req );
           UTL_HTTP.READ_LINE ( resp, v_line, TRUE );
           v_text := v_text || v_line;
           UTL_HTTP.END_RESPONSE( resp );  
         
     ELSE
           v_param_length  := LENGTHB(v_param);
           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/json');
           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);
           UTL_HTTP.READ_LINE(resp, v_text, TRUE);
           UTL_HTTP.END_RESPONSE(resp);
     END IF;
     return v_text;
 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;

2.创建ACL并授予权限

sql 复制代码
-- 验证数据库用户是否存在
SELECT username FROM dba_users WHERE username = 'WXGZH';

-- 如果用户不存在,创建用户
BEGIN
  EXECUTE IMMEDIATE 'CREATE USER wxgzh IDENTIFIED BY password'; -- 替换 password 为实际密码
  EXECUTE IMMEDIATE 'GRANT CONNECT TO wxgzh';
END;

-- 创建 ACL 并授予权限
BEGIN
  DBMS_NETWORK_ACL_ADMIN.CREATE_ACL(
    acl         => 'http_request_acl.xml',
    description => 'Allow HTTP requests',
    principal   => 'WXGZH', -- 确保使用正确的大小写
    is_grant    => TRUE,
    privilege   => 'connect'
  );

  DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL(
    acl         => 'http_request_acl.xml',
    host        => '192.168.0.19',
    lower_port  => 18882,
    upper_port  => 18882
  );
END;

-- 提交更改
COMMIT;

-- 验证 ACL 配置
SELECT acl, principal, privilege, is_grant
FROM dba_network_acl_privileges
WHERE principal = 'WXGZH'; -- 确保使用正确的大小写

3.测试HTTP请求函数

sql 复制代码
-- 测试 HTTP 请求函数
SELECT HTTP_REQUEST('http://192.168.0.1:8080/commonMsg/pushMsg?id=2', '{}', 'POST') AS data FROM dual;

其他操作

sql 复制代码
-- 查询ACL的权限
-- 字段说明 ACL-文件所在位置,principal-拥有权限的用户名,privilege-拥有的权限
SELECT * FROM dba_network_acl_privileges

-- 查询ACL开放的ip端口权限
SELECT * FROM DBA_NETWORK_ACLS


-- 追加ip
BEGIN
DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL(
    acl         => 'http_request_acl.xml',
    host        => '127.0.0.1',
    lower_port  => 8080,
    upper_port  => 8080
);
END;
COMMIT;

一点建议

在oracle中发起http请求对oracle压力比较大,建议不要将完整报文都丢给oracle进行调用。

建议的方式是,请求报文在某个地方存储起来,然后入参就传递一个ID。接收方通过ID进行查询完整的报文。

参考文档

链接: 一篇文章带你了解Oracle 11G 中的访问控制列表 (ACL)

相关推荐
TDengine (老段)6 分钟前
TDengine 支持的平台汇总
大数据·数据库·物联网·时序数据库·iot·tdengine·涛思数据
大熊猫侯佩43 分钟前
由一个 SwiftData “诡异”运行时崩溃而引发的钩深索隐(四)
数据库·swiftui·apple watch
想用offer打牌1 小时前
面试官问:Redis和MySQL数据一致,为什么还需要MySQL?🤠
数据库·redis·mysql
chen.@-@1 小时前
后端下载限速(redis记录实时并发,bucket4j动态限速)
数据库·redis·缓存
王小小鸭2 小时前
【Oracle APEX开发小技巧12】
数据库·oracle
噼里啪啦啦.2 小时前
Spring事务和事务传播机制
数据库·sql·spring
搬码红绿灯2 小时前
MySQL主从复制深度解析:原理、架构与实战部署指南
数据库·mysql·架构
呼拉拉呼拉2 小时前
Redis高可用架构
数据库·redis·架构·高可用架构
却尘2 小时前
当全世界都在用 Rust 重写一切时,Prisma 却选择了反方向
前端·数据库·orm
小吕学编程2 小时前
HttpServletRequest常用方法
java·http