ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

oracle调用http接口,并处理中文乱码问题

2021-04-02 00:00:04  阅读:519  来源: 互联网

标签:http -- end UTL acl 乱码 oracle HTTP


最近要做一个监控oracle数据库中某张表变动后往另一个数据库中写入数据的应用。
思路:数据库某张表数据变动时需要把这些数据写入另外一个数据库的表中,写一个http接口,在数据库表中有数据变动时将数据传给http接 口,并进行相应业务操作。
主要问题:数据存在中文时,会报错或乱码问题,网上很多处理的文章但是都描述的都比较模糊或者复杂,总结了网上很多方法,在此做一下记录。
1.首先是数据库层面的操作,这些网上一大堆,就单纯做下记录吧。
借鉴自:oracle通过触发器发送http请求

---创建触发器
create or replace trigger Test
after insert
on hip_nis_message --监听该张表的insert操作
for each row
declare
json varchar(4000);
begin
 --将参数拼接成JSON字符串并赋值给json变量,传入P_TEST存储过程
 json := '{"method":"NIS_MSG","mid":"'||:new.MESSAGEID||'","sendUsr":"'||:new.SENDUSR||'"}';
 P_TEST(json);--执行存储过程
end Test;
------------------------------------------------------
--创建存储过程调用http接口
create or replace procedure P_TEST(json in varchar2) as
begin
  DECLARE
      req   UTL_HTTP.REQ;
      resp  UTL_HTTP.RESP;
      value VARCHAR2(1024);  -- 缓存
      v_url VARCHAR2(4000) :='http://127.0.0.1:8086/test-http/MessageService/p?param='||**UTL_RAW.CAST_TO_RAW(json)**;                         --将json参数进行16进制编码,否则中文会报异常或者乱码
      v_param VARCHAR2(4000) := '1';            --本来是做为请求报文的,现在请求报文拼接到url地址上去了                                  
      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));--UTL_RAW.CAST_TO_RAW这个好像不能省略,没有详细测试
      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 P_TEST;
--------------------------------------------------------------
---ACL授权,必须使用数据库sys级别的账号执行
begin
    dbms_network_acl_admin.create_acl (  -- 创建访问控制文件(ACL)
    acl         => 'utl_http.xml',       -- 文件名称
    description => 'HTTP Access',        -- 描述
    principal   => 'TEST01',             -- 授权或者取消授权账号,大小写敏感
    is_grant    => TRUE,                 -- 授权还是取消授权
    privilege   => 'connect',            -- 授权或者取消授权的权限列表
    start_date  => null,                 -- 起始日期
    end_date    => null                  -- 结束日期
    );
   
    dbms_network_acl_admin.add_privilege (    -- 添加访问权限列表项
    acl        => 'utl_http.xml',             -- 刚才创建的acl名称 
    principal  => 'TEST01',                   -- 授权或取消授权用户,大小写敏感
    is_grant   => TRUE,                       -- 与上同 
    privilege  => 'resolve',                  -- 权限列表
    start_date => null,                     
    end_date   => null
    );
   
    dbms_network_acl_admin.assign_acl (     -- 使用oracle网络访问包,所允许访问的目的主机,及其端口范围。
    acl        => 'utl_http.xml',
    host       => '127.0.0.1',              -- ip地址或者域名,需要使用ip,不要使用localhost,oracle不是本机安装会异常
    lower_port => 8080,                     -- 允许访问的起始端口号
    upper_port => Null                      -- 允许访问的截止端口号
    );
    commit;
    end;
-------------------------------------------------------------
--移除ACL
  begin
    dbms_network_acl_admin.unassign_acl(
    acl        => 'nis_utl_http.xml',
    host       => '127.0.0.1',                                                  
    lower_port => 8080,                     
    upper_port => Null   
    );
  end;
  --删除用户的权限
  begin
    dbms_network_acl_admin.delete_privilege(
    'utl_http.xml', 'PINGTAI', NULL, 'resolve'
    );
  end;
  -- 删除acl配置文件
  begin
    dbms_network_acl_admin.drop_acl(
      'utl_http.xml'
    );
  end;
  1. java代码部分
/**16进制参数转换回原字符串文本
param s 16进制参数
*/
public static String toStringHex(String s){
        String result = "";
        byte[] baKeyword = new byte[s.length() / 2];
        for (int i = 0; i < baKeyword.length; i++) {
            try {
                baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(
                        i * 2, i * 2 + 2), 16));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            result = new String(baKeyword, "GBK");
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return result;
    }

*借鉴了网上很多大神的文章,如有问题请提醒我!

标签:http,--,end,UTL,acl,乱码,oracle,HTTP
来源: https://blog.csdn.net/qq_39143632/article/details/115387284

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有