Skip to main content
BreakawayPaul
Inspiring
April 22, 2014
Question

Sending XML formatted text to web service

  • April 22, 2014
  • 18 replies
  • 7251 views

I have a series of forms that send information to various web services.

One is a login form, which consists of a username/password combo, and some other credentials specified in the code.  My CF code looks like this:

<cfinvoke

    webservice="https://my.web.service.url/login?wsdl"

    method="userLookupBySession"

    returnvariable="appauth">

        <cfinvokeargument name="applicationName" value="MYAPP" />

        <cfinvokeargument name="accessCode" value="123456" />

        <cfinvokeargument name="sessionId" value="#session.appid#" />

        <cfinvokeargument name="endUserIPAddress" value="#CGI.REMOTE_ADDR#" />

</cfinvoke>

And that works quite well.

Another form is a registration form.  Like the one above, it accepts four arguments.

  • Application name
  • Access code
  • User data, formatted as XML
  • User's IP address.

Here's my code:

<cfxml variable="userData">

<cfoutput>

<USER xmlns:xsi="_http://www.w3.org/2001/XMLSchema-instance">

    <ROW NUM="1">

        <LOGIN_ID>#htmleditformat(userid)#</LOGIN_ID>

        <PASSWORD>#htmleditformat(FORM.password)#</PASSWORD>

        <NAME_LAST>#htmleditformat(FORM.name_last)#</NAME_LAST>

        <NAME_FIRST>#htmleditformat(FORM.name_first)#</NAME_FIRST>

        <NAME_MI></NAME_MI>

        <EMAIL>#htmleditformat(FORM.email)#</EMAIL>

        <OFFICE_PHONE>#htmleditformat(FORM.office_phone)#</OFFICE_PHONE>

        <OFFICE_EXT>#htmleditformat(FORM.office_ext)#</OFFICE_EXT>

        <OFFICE_FAX></OFFICE_FAX>

        <OFFICE_STREET1>#htmleditformat(FORM.office_street1)#</OFFICE_STREET1>

        <OFFICE_STREET2>#htmleditformat(FORM.office_street2)#</OFFICE_STREET2>

        <OFFICE_CITY>#htmleditformat(FORM.office_city)#</OFFICE_CITY>

        <OFFICE_STATE>#htmleditformat(FORM.office_state)#</OFFICE_STATE>

        <OFFICE_ZIP>#htmleditformat(FORM.office_zip)#</OFFICE_ZIP>

        <ORG_TYPE>#htmleditformat(FORM.org_type)#</ORG_TYPE>

        <ORG_NAME>#htmleditformat(FORM.org_name)#</ORG_NAME>

        <USER_TYPE>J</USER_TYPE>

    </ROW>

</USER>

</cfoutput>

</cfxml>

And:

<cfinvoke

    webservice="https://my.web.service.url/register?wsdl"

    method="registerRequest"

    returnvariable="regged">

        <cfinvokeargument name="applicationName" value="MYAPP" />

        <cfinvokeargument name="accessCode" value="123456" />

        <cfinvokeargument name="userData" value="#userData#" />

        <cfinvokeargument name="endUserIPAddress" value="#CGI.REMOTE_ADDR#" />

</cfinvoke>

For some reason this fails, but if I have one of the server guys use the raw XML data, it works fine, so there's something wrong with my cfinvoke.

Has anyone else passed XML data to a web service?  Is there any special thing you need to do to format it?

    This topic has been closed for replies.

    18 replies

    Legend
    April 22, 2014

    Sometimes there can be a BOM (Byte Order Mark) in the XML that can upset things (see http://stackoverflow.com/questions/6480243/coldfusion-content-not-allowed-in-prolog-xml-with-no-bom for example). Check that and also trim the userData variable to make sure there's no whitespace before the first tag in the XML data.

    Can you please cfdump your XML object (userData) and paste it here please? Have you also tried just passing a raw XML payload, rather than using CFXML? Worth a try. I don't use CXXML myself; I generally build the XML string literally and place in the values.

    BreakawayPaul
    Inspiring
    April 22, 2014

    I just tried replacing CFXML with cfsavecontent and dumping the XML file right into there (trimmed) but I got the same.

    I tried replacing cfinvoke with cfhttp to no avail, although I do get a different error.'

    <cfhttp url="https://my.web.service.url/register?wsdl" method="post" result="regged">

        <cfhttpparam type="header" name="SOAPAction" value="""....""" />

        <cfhttpparam type="header" name="applicationName-type" value="MYAPP">

        <cfhttpparam type="header" name="accessCode" value="123456">

        <cfhttpparam type="xml" name="userData" value="#trim(userData)#">

        <cfhttpparam type="header" name="endUserIPAddress" value="#CGI.REMOTE_ADDR#">

    </cfhttp>

    Error is: org.xml.sax.SAXException: Bad envelope tag: USER

    I wonder if this is because I'm not specifying the method like I am in the cfinvoke.

    The raw XML (dumped) is:

    <USER xmlns:xsi="_http://www.w3.org/2001/XMLSchema-instance">

    <ROW NUM="1">

    <LOGIN_ID>JDOE</LOGIN_ID>

    <PASSWORD>xxxxxxxxx</PASSWORD>

    <NAME_LAST>Doe</NAME_LAST>

    <NAME_FIRST>John</NAME_FIRST>

    <NAME_MI></NAME_MI>

    <EMAIL>me@myemail.com</EMAIL>

    <OFFICE_PHONE>202-555-1212</OFFICE_PHONE>

    <OFFICE_EXT></OFFICE_EXT>

    <OFFICE_FAX></OFFICE_FAX>

    <OFFICE_STREET1>1200 New Jersey Ave, NE</OFFICE_STREET1>

    <OFFICE_STREET2></OFFICE_STREET2>

    <OFFICE_CITY>Washington</OFFICE_CITY>

    <OFFICE_STATE>DC</OFFICE_STATE>

    <OFFICE_ZIP>20590</OFFICE_ZIP>

    <ORG_TYPE>Fed</ORG_TYPE>

    <ORG_NAME>FHWA</ORG_NAME>

    <USER_TYPE>J</USER_TYPE>

    </ROW>

    </USER>

    Legend
    April 22, 2014

    The error (bad envelope) seems to imply it's an endpoint issue and is not the XML itself (which looks ok). Should you be using the WSDL location rather than the resource endpoint location? Time to check the documentation for the API you are using.

    This is a good article on SOAP calls in ColdFusion and uses the same syntax for some SOAP calls that we use to various APIs:

    http://www.bennadel.com/blog/1809-making-soap-web-service-requests-with-coldfusion-and-cfhttp.htm

    Notice how the SOAP envelope has a different XML syntax to what you are using. Perhaps try that syntax?

    Also, I'm not sure the:

    <cfhttpparam type="header" name="SOAPAction" value="""....""" />

    is correct. All of our API/SOAP code has a value provided by the API for the SOAPAction value. Perhaps you should see if you can find one to use from the documentation? Our code also differs in that we have "body" as the the xml parameter name:

    <cfhttpparam type="xml" name="body" value="#xmlPayload#">