Oracle调用JAVA接口

背景

在oracle中,存储过程不能很好的完成一个业务,所以还是需要通过java程序去完一个个业务,因为oracle的特性,所以我们必须打通与java程序的通讯问题,在此记录打通的流程。

oracle创建ACL

  1. 把下面程序放到oracle的查询控制台并修改一些数据后执行(放入后可能参数名爆红 不用在意,修改相应参数直接执行即可)

    -- 添加acl和权限控制(sql语句执行的方式来执行)
    begin
        dbms_network_acl_admin.create_acl (       -- 创建访问控制文件(ACL)
                acl         => 'acl_name.xml',          -- 文件名称
                description => 'HTTP Access',           -- 描述
                principal   => 'N2ADMIN',             -- 授权或者取消授权账号,大小写敏感
                is_grant    => TRUE,                    -- 授权还是取消授权
                privilege   => 'connect',               -- 授权或者取消授权的权限列表
                start_date  => null,                    -- 起始日期
                end_date    => null                     -- 结束日期
            );
    
        dbms_network_acl_admin.add_privilege (    -- 添加访问权限列表项
                acl        => 'acl_name.xml',           -- 刚才创建的acl名称 
                principal  => 'N2ADMIN',                    -- 授权或取消授权用户
                is_grant   => TRUE,                     -- 与上同 
                privilege  => 'resolve',                -- 权限列表
                start_date => null,
                end_date   => null
            );
    
        dbms_network_acl_admin.assign_acl (       -- 该段命令意思是允许访问acl名为utl_http.xml下授权的用户,使用oracle网络访问包,所允许访问的目的主机,及其端口范围。
                acl        => 'acl_name.xml',
                host       => '192.0.0.100',           -- ip地址或者域名,填写https://localhost:8080/hello与https://localhost:8080/是会报host无效的
        -- 且建议使用ip地址或者使用域名,若用localhost,当oracle不是安装在本机上的情况下,会出现问题
                lower_port => 8080,                     -- 允许访问的起始端口号
                upper_port => Null                      -- 允许访问的截止端口号
            );
        commit;
    end;
    
    

    注:acl文件名任意,保持一致即可,principal,host,lower_port,upper_port参数保证正确即可。

    创建好即可测试。

测试案例

  1. 先写一个调用接口的公用存储过程

    create PROCEDURE P_MES_POST(M_JSON     IN VARCHAR2, --请求报文JSON格式
                                               M_URL      IN VARCHAR2, --请求接口地址
                                               M_RESPONSE OUT VARCHAR2, --返回报文JSON格式
                                               RES        OUT VARCHAR2 --返回值
                                               ) AS
      REQ    utl_http.req;
      RESP   utl_http.resp;
      V_LINE varchar2(4000);
    BEGIN
      RES := 'OK:';
      IF M_JSON IS NULL THEN
        RES := 'NG:' || '请求报文为空';
        RETURN;
      END IF;
      IF M_URL IS NULL THEN
        RES := 'NG:' || '请求接口地址为空';
        RETURN;
      END IF;
      REQ := utl_http.begin_request(M_URL, 'POST');
      utl_http.set_body_charset('UTF-8');
      utl_http.set_header(REQ, 'Content-Type', 'application/json;charset=utf-8');
    
     
      utl_http.set_header(REQ, 'Content-Length', lengthb(M_JSON));
      utl_http.write_text(REQ, M_JSON);
    
       RESP :=utl_http.get_response(REQ) ;
    
      LOOP
        utl_http.read_line(RESP, V_LINE);
       
        M_RESPONSE := M_RESPONSE || V_LINE;
        --DBMS_OUTPUT.PUT_LINE('请求json ' || M_JSON);
        --DBMS_OUTPUT.PUT_LINE('返回json ' || M_RESPONSE);
      END LOOP;
    EXCEPTION
      WHEN utl_http.end_of_body THEN
        utl_http.end_response(RESP);
      WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE(sqlerrm);
        utl_http.end_response(resp);
        utl_http.end_request(req);
        RES := 'NG:' || sqlerrm ;
    END;
    /
    
  2. 调用demo(该例子是PDA调用存储过程,存储过程调用java程序)

    create PROCEDURE "P_WH_FACTORY_ALLOT_UPDATE"(M_DOC IN VARCHAR2, --调拨单号
                                                 M_HANDOVER_EMP IN VARCHAR2,--交接员工
                                                 M_DOC_NUM IN VARCHAR2, --固定写法 界面上选择的单据号
                                                 M_DATA_AUTH IN VARCHAR2, --固定写法 登录的组织机构
                                                 M_WORKSTATION_SN IN VARCHAR2, --固定写法 当前工作中心SN法 默认输入值 用于显
                                                 FLOWCODE OUT VARCHAR2, --固定写法 本存储过程执行之后流程跳转标识码
                                                 RES OUT VARCHAR2 --固定写法
    
    ) AS
    
        IN_FACTORY  VARCHAR2(20);--调入工厂
        OUT_FACTORY VARCHAR2(20);--调出工厂
        L_CODE      VARCHAR2(5); --code
        L_MSG       VARCHAR2(1000); --message
        L_URL       VARCHAR2(1000); --地址
        L_JSON      VARCHAR2(4000); -- 报文
        L_RES_JSON  VARCHAR2(1000); -- 结果
        IP          VARCHAR2(100);
        PORT        VARCHAR2(100);
    
    
    BEGIN
    
            select VALUE into IP from sy_dict_val t where dict_code = 'IP_PORT' and code = 'IP';
            select VALUE into PORT from sy_dict_val t where dict_code = 'IP_PORT' and code = 'PORT';
            L_JSON := '{' || '"M_DOC":"' || M_DOC || '","DATA_AUTH":"' ||
                      M_DATA_AUTH || '","TYPE":"A001","OUT_FACTORY":"' || OUT_FACTORY || '","IN_FACTORY":"' || IN_FACTORY ||
                      '"}';--传给后台的json数据
            L_URL := 'http://' || IP || ':' || PORT || '/mc/http/interface.ms?model=FactoryAllotAPI&method=FactoryAllotAPI';--url
            p_mes_post(m_json => L_JSON,
                           m_url => L_URL,
                           m_response => L_RES_JSON,
                           res => RES);
            --解析传出json    {"Code":"200","Message":"接收成功"} oracle 12c
            select json_value(L_RES_JSON, '$.Code'),
                   json_value(L_RES_JSON, '$.Message')
            into L_CODE, L_MSG
            from dual;
    
            IF NVL(SUBSTR(RES, 1, 2), 'null') <> 'OK' THEN
                res := 'NG:' || '调接口出错' || L_MSG;
                RETURN;
            END IF;
            IF L_CODE = '0' THEN --接口返回code为0
                res := 'NG:' || L_MSG;--打印出后台返回的错误
                RETURN;
            else
                RES := 'OK:' || '调用成功';
            END IF;
    
    EXCEPTION
        WHEN OTHERS THEN
            RES :='NG:出现了错误!'|| sqlerrm;
        -- DBMS_OUTPUT.PUT_LINE('出现了错误!'|| sqlerrm);
    END;
    /
    
    
    
  3. java后台(为了大家看的更清晰,我把具体业务删掉,只看返回方式即可),因为某些方法是我司自己封装的,后台仅供参考)

    package com.more.mes.warehouse;
    
    import com.more.fw.core.common.exception.AppException;
    import com.more.fw.core.common.method.CommMethod;
    import com.more.fw.core.common.method.SpringContextUtil;
    import com.more.fw.core.dbo.model.service.ModelService;
    import com.more.fw.http.service.HttpCoreService;
    import com.more.fw.http.service.IhttpServiceJosn;
    import com.more.fw.interf.InterfaceLog;
    
    
    import java.io.BufferedReader;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.PrintStream;
    import java.util.HashMap;
    import java.util.Map;
    
    
    /**
     * @author zhb
     * @data 2021年08月27日
     */
    public class FactoryAllotAPI extends InterfaceLog implements IhttpServiceJosn {
        Map<String, Object> mapMessage = new HashMap<String, Object>();
        Map<String, Object> resultMap = new HashMap<String, Object>();
    
    
        @Override
        public String exeFunc(HttpCoreService service) {
            //你的业务
            try {
                String statu = "SUCCESS";
                if ("SUCCESS".equals(statu)) {
                    mapMessage.put("Code", "200");
                    mapMessage.put("Message", "SAP Return Success:");
                    resultMap.put("json", CommMethod.toJson(mapMessage));
                    service.setResult(resultMap);
                    service.getResponse().setHeader("Content-Type", "application/json");
                    service.getResponse().setHeader("Access-Control-Allow-Origin", "*");
                    service.getResponse().setHeader("Access-Control-Allow-Methods", "POST");
                    service.getResponse().setHeader("Access-Control-Allow-Headers", "*");
    
                } else {
                    
                    mapMessage.put("Code", "0");
                    mapMessage.put("Message", "你的错误信息");
                    resultMap.put("json", CommMethod.toJson(mapMessage));
                    service.setResult(resultMap);
                    service.getResponse().setHeader("Content-Type", "application/json");
                    service.getResponse().setHeader("Access-Control-Allow-Origin", "*");
                    service.getResponse().setHeader("Access-Control-Allow-Methods", "POST");
                    service.getResponse().setHeader("Access-Control-Allow-Headers", "*");
    
                }
    
            }catch (Exception e){
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                e.printStackTrace(new PrintStream(baos));
                mapMessage.put("Code", "0");
                mapMessage.put("Message", "APP ERROR:"+baos.toString());
                resultMap.put("json", CommMethod.toJson(mapMessage));
                service.setResult(resultMap);
                service.getResponse().setHeader("Content-Type", "application/json");
                service.getResponse().setHeader("Access-Control-Allow-Origin", "*");
                service.getResponse().setHeader("Access-Control-Allow-Methods", "POST");
                service.getResponse().setHeader("Access-Control-Allow-Headers", "*");
    
            }
    
            return null;
        }
    
        /**
         * @param service 请求包
         * @return String json字符串
         * @Description: 解析请求包
         * @Author: Bryan
         * @ChangeLog: 2021年08月27日  zhb 创建方法
         */
        @SuppressWarnings({"unchecked", "rawtypes"})
        public static String getRequestJson(HttpCoreService service) {
            StringBuilder str = null;
            BufferedReader reader = null;
            try {
                reader = service.getHttpRequest().getReader();
    
                String line = null;
                str = new StringBuilder();
                while ((line = reader.readLine()) != null) {
                    str.append(line);
                }
            } catch (Exception e) {
                throw new AppException(e);
            } finally {
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return str.toString();
        }
    }
    
    
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想吃饼干吗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值