You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用APEX_WEB_SERVICE调用SOAP服务遇ORA-30625错误求助

排查与解决APEX_WEB_SERVICE调用SOAP服务时的ORA-30625错误

调用SOAP Web服务时触发ORA-30625: method dispatch on NULL SELF argument is disallowed错误,SOAP-UI中请求可正常执行,但PL/SQL代码无法正常运行,代码如下:

declare
    l_token                VARCHAR2(32767);
    l_envelope             CLOB;
    l_xml                  XMLTYPE;
    l_result               VARCHAR2(32767);
BEGIN

 l_envelope := q'!<?xml version='1.0' encoding='UTF-8'?>!';
   l_envelope := l_envelope || '<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ws="http://ws.mcel.co.mz/">
   <soap:Header/>
   <soap:Body>
      <ws:getMsisdnAndAvailabilityFromSerial>
         <simCardSerial>8925801191077167862</simCardSerial>
         <loginInfo>
            <!--Optional:-->
            <nomeAplicacao>***</nomeAplicacao>
            <!--Optional:-->
            <usuario>***</usuario>
            <!--Optional:-->
            <password>***</password>
            <!--Optional:-->
            <token>***</token>
         </loginInfo>
      </ws:getMsisdnAndAvailabilityFromSerial>
   </soap:Body>
</soap:Envelope>';

    -- Aqui, certifique-se de que todas as instâncias de objetos não são nulas
    IF l_envelope IS NOT NULL THEN
        l_xml := XMLTYPE.createXML(l_envelope);
    ELSE
        -- Lidar com o caso onde l_envelope é NULL
        RAISE_APPLICATION_ERROR(-20001, 'Envelope é NULL');
    END IF;
--
    --   l_xml := xmltype(l_envelope);
        dbms_output.put_line('Envelope SOAP: ' || l_envelope);
        l_xml := apex_web_service.make_request(p_url => 'http://ServerIP/SimRegWebService', p_action => 'http://ServerIP/SimRegWebService/getMsisdnAndAvailabilityFromSerial'
        , p_envelope => l_envelope);

        dbms_output.put_line('Resposta SOAP: ' || l_xml.getclobval());
        l_result := apex_web_service.parse_xml(p_xml => l_xml, p_xpath => '', 
        p_ns => 'xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ws="http://ws.mcel.co.mz/"');

        dbms_output.put_line('Resultado: ' || l_result);

EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('Erro: ' || SQLERRM);

    END;

排查方向与解决方案

ORA-30625错误本质是调用对象方法时,对象实例为NULL,结合代码和SOAP服务特性,重点排查以下几点:

1. 检查apex_web_service.make_request的返回值

当Web服务请求失败(网络不通、URL错误、权限限制等),make_request可能返回NULL。后续调用l_xml.getclobval()时,因为l_xml是NULL,直接触发错误。

解决: 在使用l_xml前增加非空判断:

-- 调用Web服务后增加判断
IF l_xml IS NOT NULL THEN
    dbms_output.put_line('Resposta SOAP: ' || l_xml.getclobval());
ELSE
    DBMS_OUTPUT.PUT_LINE('Erro: Web服务请求未返回有效XML');
END IF;

2. 修正p_action参数的正确性

SOAP Action值必须与服务端要求完全一致,代码中当前的p_action用了服务器URL拼接方法名,大概率不符合要求。可以从SOAP-UI的请求头中复制准确的SOAP Action值(通常是命名空间+方法名,比如http://ws.mcel.co.mz/getMsisdnAndAvailabilityFromSerial)。

解决: 替换p_action为SOAP-UI中验证过的正确值。

3. 优化SOAP信封的构建方式

代码中手动拼接XML时使用了大量转义字符,容易导致XML格式错误,虽然SOAP-UI能处理,但PL/SQL解析时可能出问题。

解决: 用q'[...]'直接引用完整XML,避免转义错误:

l_envelope := q'[<?xml version='1.0' encoding='UTF-8'?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ws="http://ws.mcel.co.mz/">
   <soap:Header/>
   <soap:Body>
      <ws:getMsisdnAndAvailabilityFromSerial>
         <simCardSerial>8925801191077167862</simCardSerial>
         <loginInfo>
            <nomeAplicacao>***</nomeAplicacao>
            <usuario>***</usuario>
            <password>***</password>
            <token>***</token>
         </loginInfo>
      </ws:getMsisdnAndAvailabilityFromSerial>
   </soap:Body>
</soap:Envelope>]';

4. 确认数据库服务器的网络与权限

SOAP-UI在本地能访问服务,但数据库服务器可能没有目标URL的访问权限,或者网络不通。

解决: 在数据库服务器上测试目标URL的连通性,同时检查数据库的ACL权限配置(确保APEX_WEB_SERVICE有权限访问外部网络)。

5. 避免解析空XML

如果l_xml为NULL,调用apex_web_service.parse_xml也会触发错误,需要提前判断。

解决: 解析前增加非空判断:

IF l_xml IS NOT NULL THEN
    l_result := apex_web_service.parse_xml(p_xml => l_xml, p_xpath => '', 
    p_ns => 'xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ws="http://ws.mcel.co.mz/"');
    dbms_output.put_line('Resultado: ' || l_result);
ELSE
    DBMS_OUTPUT.PUT_LINE('Erro: 无法解析空的XML响应');
END IF;

修改后的完整代码示例

declare
    l_token                VARCHAR2(32767);
    l_envelope             CLOB;
    l_xml                  XMLTYPE;
    l_result               VARCHAR2(32767);
BEGIN
    -- 直接引用完整XML,避免转义错误
    l_envelope := q'[<?xml version='1.0' encoding='UTF-8'?>
    <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ws="http://ws.mcel.co.mz/">
       <soap:Header/>
       <soap:Body>
          <ws:getMsisdnAndAvailabilityFromSerial>
             <simCardSerial>8925801191077167862</simCardSerial>
             <loginInfo>
                <nomeAplicacao>***</nomeAplicacao>
                <usuario>***</usuario>
                <password>***</password>
                <token>***</token>
             </loginInfo>
          </ws:getMsisdnAndAvailabilityFromSerial>
       </soap:Body>
    </soap:Envelope>]';

    dbms_output.put_line('Envelope SOAP: ' || l_envelope);
    
    -- 调用Web服务,替换为正确的SOAP Action
    l_xml := apex_web_service.make_request(
        p_url => 'http://ServerIP/SimRegWebService', 
        p_action => 'http://ws.mcel.co.mz/getMsisdnAndAvailabilityFromSerial',
        p_envelope => l_envelope
    );

    -- 检查XML响应是否为空
    IF l_xml IS NOT NULL THEN
        dbms_output.put_line('Resposta SOAP: ' || l_xml.getclobval());
        
        -- 解析XML结果
        l_result := apex_web_service.parse_xml(
            p_xml => l_xml, 
            p_xpath => '', 
            p_ns => 'xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ws="http://ws.mcel.co.mz/"'
        );
        dbms_output.put_line('Resultado: ' || l_result);
    ELSE
        DBMS_OUTPUT.PUT_LINE('Erro: Web服务请求未返回有效XML');
    END IF;

EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('Erro: ' || SQLERRM);
END;
/

内容的提问来源于stack exchange,提问作者nelio mboana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 00:50:24