Skip to Main Content

SQL & PL/SQL

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

SOAP request via UTL_HTTP = 400 bad request

d3bruts1dFeb 25 2014 — edited Feb 25 2014

I'm trying to send a SOAP request to another group within my company. They have a service (with WSDL) created which is used by other groups. I'm trying to send the request though our database using UTL_HTTP, however every request I've sent returns a 400: Bad Request response.

The WSDL they have published looks like this:

<?xml version="1.0" encoding="utf-8"?>

<wsdl:definitions name="Query" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:tns="http://tempuri.org/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata">

  <wsp:Policy wsu:Id="BasicHttpBinding_IQuery_policy">

    <wsp:ExactlyOne>

      <wsp:All>

        <sp:TransportBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">

          <wsp:Policy>

            <sp:TransportToken>

              <wsp:Policy>

                <sp:HttpsToken RequireClientCertificate="false"/>

              </wsp:Policy>

            </sp:TransportToken>

            <sp:AlgorithmSuite>

              <wsp:Policy>

                <sp:Basic256/>

              </wsp:Policy>

            </sp:AlgorithmSuite>

            <sp:Layout>

              <wsp:Policy>

                <sp:Strict/>

              </wsp:Policy>

            </sp:Layout>

          </wsp:Policy>

        </sp:TransportBinding>

      </wsp:All>

    </wsp:ExactlyOne>

  </wsp:Policy>

  <wsdl:types>

    <xsd:schema targetNamespace="http://tempuri.org/Imports">

      <xsd:import schemaLocation="https://mydomain.com/MetWcfService/Query.svc?xsd=xsd0" namespace="http://tempuri.org/"/>

      <xsd:import schemaLocation="https://mydomain.com/MetWcfService/Query.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>

      <xsd:import schemaLocation="https://mydomain.com/MetWcfService/Query.svc?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/"/>

    </xsd:schema>

  </wsdl:types>

  <wsdl:message name="IQuery_GetLatestValueForParameter_InputMessage">

    <wsdl:part name="parameters" element="tns:GetLatestValueForParameter"/>

  </wsdl:message>

  <wsdl:message name="IQuery_GetLatestValueForParameter_OutputMessage">

    <wsdl:part name="parameters" element="tns:GetLatestValueForParameterResponse"/>

  </wsdl:message>

  <wsdl:message name="IQuery_GetLatestValueForParameters_InputMessage">

    <wsdl:part name="parameters" element="tns:GetLatestValueForParameters"/>

  </wsdl:message>

  <wsdl:message name="IQuery_GetLatestValueForParameters_OutputMessage">

    <wsdl:part name="parameters" element="tns:GetLatestValueForParametersResponse"/>

  </wsdl:message>

  <wsdl:portType name="IQuery">

    <wsdl:operation name="GetLatestValueForParameter">

      <wsdl:input wsaw:Action="http://tempuri.org/IQuery/GetLatestValueForParameter" message="tns:IQuery_GetLatestValueForParameter_InputMessage"/>

      <wsdl:output wsaw:Action="http://tempuri.org/IQuery/GetLatestValueForParameterResponse" message="tns:IQuery_GetLatestValueForParameter_OutputMessage"/>

    </wsdl:operation>

    <wsdl:operation name="GetLatestValueForParameters">

      <wsdl:input wsaw:Action="http://tempuri.org/IQuery/GetLatestValueForParameters" message="tns:IQuery_GetLatestValueForParameters_InputMessage"/>

      <wsdl:output wsaw:Action="http://tempuri.org/IQuery/GetLatestValueForParametersResponse" message="tns:IQuery_GetLatestValueForParameters_OutputMessage"/>

    </wsdl:operation>

  </wsdl:portType>

  <wsdl:binding name="BasicHttpBinding_IQuery" type="tns:IQuery">

    <wsp:PolicyReference URI="#BasicHttpBinding_IQuery_policy"/>

    <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>

    <wsdl:operation name="GetLatestValueForParameter">

      <soap:operation soapAction="http://tempuri.org/IQuery/GetLatestValueForParameter" style="document"/>

      <wsdl:input>

        <soap:body use="literal"/>

      </wsdl:input>

      <wsdl:output>

        <soap:body use="literal"/>

      </wsdl:output>

    </wsdl:operation>

    <wsdl:operation name="GetLatestValueForParameters">

      <soap:operation soapAction="http://tempuri.org/IQuery/GetLatestValueForParameters" style="document"/>

      <wsdl:input>

        <soap:body use="literal"/>

      </wsdl:input>

      <wsdl:output>

        <soap:body use="literal"/>

      </wsdl:output>

    </wsdl:operation>

  </wsdl:binding>

  <wsdl:service name="Query">

    <wsdl:port name="BasicHttpBinding_IQuery" binding="tns:BasicHttpBinding_IQuery">

      <soap:address location="https://mydomain.com/MetWcfService/Query.svc"/>

    </wsdl:port>

  </wsdl:service>

</wsdl:definitions>

Now, plugging in the WSDL into WCF Test Client (from VS) tells me that the request envelope should look like this:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">

  <s:Header>

    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IQuery/GetLatestValueForParameter</Action>

  </s:Header>

  <s:Body>

    <GetLatestValueForParameter xmlns="http://tempuri.org/">

      <p xmlns:d4p1="http://schemas.datacontract.org/2004/07/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">

        <d4p1:ParameterName>TP02</d4p1:ParameterName>

        <d4p1:SiteName>XXXX</d4p1:SiteName>

        <d4p1:TowerName>2006TWR</d4p1:TowerName>

      </p>

    </GetLatestValueForParameter>

  </s:Body>

</s:Envelope>

Processing that request through the WCF Test Client gives me the response I expect to see. So, I moved on to my PL/SQL procedure, which is currently a combination of some information I found online.

DECLARE
    l_http_request   UTL_HTTP.req;
    l_http_response  UTL_HTTP.resp;
    l_buffer_size    NUMBER(10) := 512;
    l_line_size      NUMBER(10) := 50;
    l_lines_count    NUMBER(10) := 80;
    l_string_request VARCHAR2(4000);
    l_line           VARCHAR2(4000);
    l_substring_msg  VARCHAR2(4000);
    l_raw_data       RAW(4000);
    l_clob_response  CLOB;

BEGIN
  utl_http.set_wallet('file:E:\Oracle\product\11.2.0\dbhome_1\BIN\owm\wallets');
  utl_http.set_proxy(null);

    l_string_request :=      
        '<SOAP-ENV:Envelope '
      ||'   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"'
      ||'   SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>'
      ||' <SOAP-ENV:Header>'
      ||'   <Action SOAP-ENV:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">GetLatestValueForParameter</Action>'
      ||' </SOAP-ENV:Header>'
      ||' <SOAP-ENV:Body>'
      ||'   <m:GetLatestValueForParameter xmlns:m="http://schemas.datacontract.org/2004/07/">'
      ||'      <p xmlns:d4p1="http://schemas.datacontract.org/2004/07/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">'
      ||'       <ParameterName>TP02</ParameterName>'
      ||'       <SiteName>XXXX</SiteName>'
      ||'       <TowerName>2006TWR</TowerName>'
      ||'     </p>'
      ||'   </m:GetLatestValueForParameter>'
      ||' </SOAP-ENV:Body>'
      ||'</SOAP-ENV:Envelope>';

    UTL_HTTP.set_transfer_timeout(60);
    l_http_request := UTL_HTTP.begin_request(url => 'https://mydomain.com/MetWcfService/Query.svc?wsdl', method => 'POST', http_version => UTL_HTTP.http_version_1_1);

    UTL_HTTP.set_header(l_http_request, 'User-Agent', 'Mozilla/4.0');
    UTL_HTTP.set_header(l_http_request, 'Content-Type', 'text/xml;charset=utf-8');
    UTL_HTTP.set_header(l_http_request, 'SOAPAction');
    UTL_HTTP.set_header(l_http_request, 'Content-Length', LENGTH(l_string_request));

    <<request_loop>>
    FOR i IN 0..CEIL(LENGTH(l_string_request) / l_buffer_size) - 1 LOOP
        l_substring_msg := SUBSTR(l_string_request, i * l_buffer_size + 1, l_buffer_size);

        BEGIN
            l_raw_data := utl_raw.cast_to_raw(l_substring_msg);
            UTL_HTTP.write_raw(r => l_http_request, data => l_raw_data);
            EXCEPTION
                WHEN NO_DATA_FOUND THEN
                    EXIT request_loop;
        END;
    END LOOP request_loop;

    l_http_response := UTL_HTTP.get_response(l_http_request);
    DBMS_OUTPUT.put_line('Response> status_code: "' || l_http_response.status_code || '"');
    DBMS_OUTPUT.put_line('Response> reason_phrase: "' ||l_http_response.reason_phrase || '"');
    DBMS_OUTPUT.put_line('Response> http_version: "' ||l_http_response.http_version || '"');

    BEGIN

        <<response_loop>>
        LOOP
            UTL_HTTP.read_raw(l_http_response, l_raw_data, l_buffer_size);
            l_clob_response := l_clob_response || UTL_RAW.cast_to_varchar2(l_raw_data);
        END LOOP response_loop;

        EXCEPTION
            WHEN UTL_HTTP.end_of_body THEN
                UTL_HTTP.end_response(l_http_response);
    END;
    DBMS_OUTPUT.put_line('Response> length: "' || LENGTH(l_clob_response) || '"');
    DBMS_OUTPUT.put_line(CHR(10) || '=== Print first ' || l_lines_count || ' lines of HTTP response... ===' || CHR(10) || CHR(10));

    <<print_response>>
    FOR i IN 0..CEIL(LENGTH(l_clob_response) / l_line_size) - 1 LOOP
        l_line := SUBSTR(l_clob_response, i * l_line_size + 1, l_line_size);
        DBMS_OUTPUT.put_line('[' || LPAD(i, 2, '0') || ']: ' || l_line);
        EXIT WHEN i > l_lines_count - 1;
    END LOOP print_response;

    IF l_http_request.private_hndl IS NOT NULL THEN
        UTL_HTTP.end_request(l_http_request);
    END IF;

    IF l_http_response.private_hndl IS NOT NULL THEN
        UTL_HTTP.end_response(l_http_response);
    END IF;

END;
/

The result ends up being:

Response> status_code: "400"

Response> reason_phrase: "Bad Request"

Response> http_version: "HTTP/1.1"

Response> length: ""

Based on this, I assume that there is either an issue with my XML syntax or the SOAP envelope. Any ideas where I've gone wrong?

Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Mar 25 2014
Added on Feb 25 2014
2 comments
2,356 views