3

I am trying to consume a WSDL from ColdFusion using cfinvoke tag and I am having problems passing arguments. If it's a simple STRING or NUMERIC argument, it works good. The problem is when I need to pass this argument:

<part name="options" type="soap-enc:Array"/>

Well, I tried different ways: pass a ColdFusion ARRAY, STRUCT, simple string, etc. Nothing works. In some cases I got a response from the web service telling that the parameter is missing and when I pass a structure, I am getting this error:

Error converting CFML arguments to Java classes for web service invocation. Unable to create web service argument class [Ljava.lang.Object;. Error: java.lang.InstantiationException: [Ljava.lang.Object;. Often this is because the web service defines an abstract complexType as an input to an operation. You must create an actual instance of this type in Java.

You can see the script in action here:

cf wsdl web service test

There you have the link to the web service definitions. What should I do? How do I pass simple Array objects to WSLD from ColdFusion?

3
  • 1
    Seems like it is expecting some sort of token as well? Try using createObject instead: ws = createObject("webservice", "https://api.iritravel.ro/?wsdl");. Dump the result and take a look at the getRooms() signature: token (string), idHotel (int) Commented Mar 15, 2016 at 6:34
  • It works if I need to pass only the token - here is the code <cfscript> ws = createObject("webservice", "https://api.iritravel.ro/?wsdl"); res = ws.getCountries(token = "137e8f1a094-1031"); </cfscript> But how do I provide the second parameter for getTowns method? It should be an array with CountryId code (use CountryId = 2 if you want to test) Commented Mar 15, 2016 at 7:39
  • The rpc stuff can be a little tricky. You might you considered using cfhttp + xml instead. Use SoapUI to generate the basic xml, plug in your values and submit it with cfhttp. pastebin.com/2JWSyNpT Commented Mar 15, 2016 at 17:24

1 Answer 1

3

The lack of transparency around complex SOAP objects like you see here are a big reason why JSON is much preferred as a data format these days. I've written Java components to deal with this kind of thing. You need to know the specific format of the options variable (the second argument), which is an array of Objects, though it gives no details. I don't have a completely working solution for you, but this code should get you most of the way there.

<cfscript>
    ws = createObject("webservice", "https://api.iritravel.ro/?wsdl");
    res = ws.getCountries(token = "137e8f1a094-1031");
    country = createObject( "java", "java.util.HashMap" ).init();
    country.put( 'CountryId', 2 );
    res2 = ws.getTowns( token = "137e8f1a094-1031", options=[ country ] );
    writedump( res2 );
    writedump( country );
</cfscript>

If I get it working I will post an update, but you might be able to get it done using what I have here. I have created a HashMap (basic Java object) and added a key "CountryId" with a value of 2. See the way I formatted the options argument as an array and passed the country HashMap object to it as the first element of the array. That bit of the code works, so you just need to know the specific format of the Object the service is expecting.

Update

I have included a SOAPUI-generated request for getTowns() which shows the problem is the same whether using webservices calls or cfhttp. In this case, I have added a CountryId parameter to the request, and what I get back is the same response I got from the previous call - param CountryId is missing. So the issue is the same - the format of the Object Array that the service is expecting to consume is incorrect.

http://pastebin.com/ZXBS2e2r

Sign up to request clarification or add additional context in comments.

11 Comments

Out of curiosity, did you have any luck getting a result? I had tried something similar with structures, but no joy. Same result with HashMap. Only thing that worked so far was cfhttp + xml.
Yes, I'm getting an error result with this code. [ { error : { code: 2, message : CountryId param is missing } } ]. So the format of the "options" Object is the issue.
Darn. I had not found the magic combination yet and was hoping you found something I missed ;-) Of course it worked right out of the box using cfhttp + xml. No such luck with cfinvoke or cfobject :/. My curious mind would still love to know the "correct" format here, but ... if time is a factor I would probably go the cfhttp route at this point.
In this case cfhttp + xml isn't going to help. My code generates a response from the server that says, "We got your request, but didn't see a CountryId". As you can see, CountryId is in the country object, it just isn't being represented the right way. I'll show the cfhttp version from SoapUI in my answer to illustrate the problem.
Adrian, you need to check with the vendor about the format of the "options" argument. This is one of the primary shortcomings of SOAP Webservices - it technically has this very detailed schema but allows for these "black holes" where there is no introspection into what you should/could send as an argument. Clearly there is a "correct" format the service is expecting, we know that because of the error we are seeing, but it provides no further information about what that correct format is. Check with the vendor.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.