I'm upgrading from ColdFusion 9 to ColdFusion 2016 and my web services suddenly no longer work. I believe it's because Axis 2 was introduced in Cold Fusion 10 and with it rendered my existing web services non-functional.
Even if I set the Web Service version back to 1 in ColdFusion Administrator, it still doesn't work.
The way I call these web services is with the createObject
function as such:
<cfscript>
objSoapHeader = XmlParse("<wsse:Security mustUnderstand=""true"" xmlns:wsse=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd""><wsse:UsernameToken><wsse:Username>USERNAME</wsse:Username><wsse:Password>PASSWORD</wsse:Password></wsse:UsernameToken></wsse:Security>");
Application.UserWebService = CreateObject("webservice", PATH & "Requests/UserService.asmx?WSDL");
addSOAPRequestHeader(Application.UserWebService,"","",objSoapHeader,true);
// Get the .Net resources
Application.NetResources = Application.UserWebService.GetNetResources();
</cfscript>
The error I recieve is :
Cannot perform web service invocation GetNetResources.
The fault returned when invoking the web service operation is:java.lang.RuntimeException: Error obtaining parser from data source:LanguageHeader cannot be null!
It states that the LangaugeHeader
cannot be null
. The WSDL displays two messages associated to the GetNetResources
operation:
<wsdl:portType name="UserServiceSoap">
<wsdl:operation name="GetNetResources">
<wsdl:input message="tns:GetNetResourcesSoapIn"/>
<wsdl:output message="tns:GetNetResourcesSoapOut"/>
</wsdl:operation>
</wsdl:portType >
However when looking at the list of messages I can see three messages associated to GetNetResources:
<wsdl:message name="GetNetResourcesSoapIn">
<wsdl:part name="parameters" element=tns:GetNetResources"/>
</wsdl:message>
<wsdl:message name="GetNetResourcesSoapOut">
<wsdl:part name="parameters" element=tns:GetNetResourcesResponse"/>
</wsdl:message>
<wsdl:message name="GetNetResourcesLanguageHeader">
<wsdl:part name="parameters" element=tns:LanguageHeader"/>
</wsdl:message>
If the operation is only specifying two messages, then where in the WSDL file is this third message being associated to the operation?
It seems that the LanguageHeader parameter is absolutely required and enfored in ColdFusion 2016, so why was it working in ColdFusion 9 (Axis 1)?
EDIT 1
To answer my first question above (striked out) I found the following code in the binding
as opposed to the portType
:
<wsdl:binding name="UserServiceSoap" type="tns:UserServiceSoap">
<wsdl:operation name="GetNetResources">
<soap:operation style="document" soapAction="http://tempuri.org/GetNetResources"/>
<wsdl:input>
<soap:body use="literal"/>
<soap:header message="tns:GetNetResourcesLanguageHeader" use="literal" part="LanguageHeader"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
However that still doesn't answer my second question.
EDIT 2
After playing around with the code a bit, I manged to resolve the RuntimeException
by adding a variable to the web service call.
args = {TEST="<locale>en-CA</locale>"};
Application.NetResources = Application.UserWebService.GetNetResources(argumentCollection=args);
Which now results in the following error:
Web service parameter name languageHeader cannot be found in the provided parameters {TEST}.
As TEST
is not an actual parameter specified in the WSDL, I modified it to languageHeader
, and recieve this new error:
Web service operation GetNetResources with parameters {LANGUAGEHEADER={<locale>en-CA</locale>}} cannot be found.
This indicates that languageHeader
is indeed the correct parameter name, however it still cannot find the the web service operation, therefore I believe the 'type' of the parameter is different.
Perhaps I'm not suppose to be sending a string as the value, however looking back at my WSDL, it states that they type of the Locale
is a string:
<wsdl:types>
<s:schema targetNamespace="http://tempuri.org/" elementFormDefault="qualified">
<s:element name="LanguageHeader" type="tns:LanguageHeader"/>
<s:complexType name="LanguageHeader">
<s:sequence>
<s:element name="Locale" type="s:string" maxOccurs="1" minOccurs="0"/>
</s:sequence>
<s:anyAttribute/>
</s:complexType>
</s:schema>
</wsdl:types>
From what I understand I'm suppose to be sending a complexType
object as the parameter which contains a Locale
as a string.
What kind of object would I be sending from CFML if that is the case?
When consuming a web service with a parameter of a complex data type, send a structure
as the parameter.
// Create struct
stLanguageHeader = structNew();
stLanguageHeader.locale = "en-CA";
Application.NetResources = Application.UserWebService.GetNetResources(stLanguageHeader);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With