为什么UTL_HTTP.GET_响应抛出HTTP协议错误

为什么UTL_HTTP.GET_响应抛出HTTP协议错误,http,plsql,oracle11g,Http,Plsql,Oracle11g,我正在使用UTL_HTTP从Oracle11g调用一个Web服务。我确信我的证书和钱包设置正确,可以通过HTTPS进行连接。对于有效的业务数据,调用始终有效 当我传递无效数据(本例中为不存在的用户id)时,对UTL_HTTP.GET_RESPONSE的调用引发异常: ORA-29273: HTTP request failed ORA-06512: at "SYS.UTL_HTTP", line 1369 ORA-29263: HTTP protocol error 我没有返回UTL_HTTP

我正在使用UTL_HTTP从Oracle11g调用一个Web服务。我确信我的证书和钱包设置正确,可以通过HTTPS进行连接。对于有效的业务数据,调用始终有效

当我传递无效数据(本例中为不存在的用户id)时,对UTL_HTTP.GET_RESPONSE的调用引发异常:

ORA-29273: HTTP request failed
ORA-06512: at "SYS.UTL_HTTP", line 1369
ORA-29263: HTTP protocol error
我没有返回UTL_HTTP.RESP对象来调查任何HTTP错误代码或内容。许多其他无效数据用例返回了带有错误代码的响应,但它们没有引发异常。我能够处理HTTP错误代码的响应,并从响应主体获取错误消息

在引发异常的特定情况下,我注意到:

  • 响应体比其他情况下更大~2600字节
  • 响应主体包含符号(这是一个HTML响应,其中包含转义的XML内容。我无法控制服务器响应)
我通过打电话给curl发现了这些。UTL_HTTP.GET_响应引发HTTP协议错误的原因是否可能是这些条件之一


谢谢。

您是否使用UTL\u ENCODE.BASE64\u ENCODE之类的东西来构建请求?尝试使用修复请求字符串
替换(您的请求,UTL_TCP.CRLF“”)

ORA-29263:HTTP协议错误
在以下情况下引发:-

  • 案例1:URL是而不是https
    -->检查URL并确保它是https而不是http

  • 案例2:钱包证书设置不正确


看起来,由
utl\u http
引发的错误是故意不透明的,除非您要求Oracle更明确一点

要在引发异常时更详细地显示错误消息,请在会话中的某个位置调用:

utl_http.set_response_error_check(true)
否则,根据
utl\u http
包本身中的文档,您可以在异常处理代码中利用以下方法获得错误:

utl_http.get_detailed_sqlcode
utl_http.get_detailed_sqlerrm
至于处理大型请求,如果这是您真正的问题,将响应分块并累积到clob中可能会解决您的问题:

function get_request(p_url varchar2, p_payload_text varchar2)
return clob
is
    v_req utl_http.req;
    v_resp utl_http.resp;
    v_req varchar2(32767);
    v_resp clob;
    v_resp_chunked varchar2(32767);
    v_xml_resp xmltype;

begin

        utl_http.set_response_error_check(true);

        v_req := utl_http.begin_request(
            url => p_url
            , method => 'POST'
            , http_version => 'HTTP/1.1'
        );
        utl_http.set_body_charset(v_req, 'UTF-8');
        utl_http.set_persistent_conn_support(false, 0);

        utl_http.set_header(v_req, 'Content-Type', 'text/xml;charset=UTF-8');
        utl_http.set_header(v_req, 'Content-Length', length(p_payload_text));


        utl_http.write_text(v_req, p_payload_text);

        v_resp := utl_http.get_response(v_req);

        dbms_output.put_line(v_resp_chunked);

        dbms_lob.createtemporary(v_resp,true, dbms_lob.session);

        begin
            loop
                utl_http.read_text(v_resp, v_resp_chunked, 32767);
                --dbms_output.put_line(v_resp_chunked);
                dbms_lob.append(v_resp, v_resp_chunked);
            end loop;

            exception
            when utl_http.end_of_body or UTL_HTTP.TOO_MANY_REQUESTS then
                utl_http.end_response(v_resp);
                dbms_output.put_line('mess:' ||SQLERRM);
        end;

        dbms_lob.freetemporary(v_resp);

        return v_resp;
end;