Steven Erat's Blog Steven Erat Photography
 
 
Viewing By Entry
 
 

TalkingTree  How to invoke a Web Service while omitting optional service method arguments

 

ColdFusion MX webservice implementations as CFCs may include optional input arguments, however consuming the webservice may prove tricky if those optional parameters are not included.

For example, consider this example webservice having one required argument (a1) and one optional argument (a2):

Webservice Producer

<cfcomponent>

<cffunction name="test1" access="remote" returntype="string" output="No">
<cfargument name="a1" required="Yes">
<cfargument name="a2" required="No" default="2">
   <!--- no method implementation for test --->
<cfreturn "It worked!">
</cffunction>

</cfcomponent>

Now consider how you might consume the webservice while only passing the required argument a1:

Webservice Consumer (Typical Syntax)

<cfinvoke webservice="http://localhost/webservice_optargs.cfc?wsdl" returnvariable="result" method="test1">
<cfinvokeargument name="a1" value="1">
<!--- <cfinvokeargument name="a2" value="2">--->
</cfinvoke>

Webservice Consumer (Alternate Syntax)

<cfobject webservice="http://localhost/webservice_optargs.cfc?wsdl" name="ws">
<cfset result = ws.test1(a1=1)>

The problem with each of these is than an error will occur which seems completely contradictory, hinting that the webservice method could not be found.

Web service operation "test1" with parameters {a1={1},} could not be found.

The error occurred in /opt/coldfusionmx/wwwroot/serat/webservice_client.cfm: line 11

11 : <cfobject webservice="http://localhost/webservice_optargs.cfc?wsdl" name="ws">
12 : <cfinvokeargument name="a1" value="1">
13 : <!--- <cfinvokeargument name="a2" value="2">--->

coldfusion.xml.rpc.ServiceProxy$ServiceMethodNotFoundException: Web service operation "test1" with parameters {a1={1},} could not be found.
at coldfusion.xml.rpc.ServiceProxy.invoke(ServiceProxy.java:136)

In brief, this is a Java "method not found" exception. Yet if you simply uncomment the second cfinvokeargument for a2 suddenly the webservice will work. I'll try to explain why the error occurs and how to solve this problem ...

When ColdFusion consumes a webservice the first time it initially generates a "stub" which acts as a Java interface to the remote webservice, according to the WSDL specification. The stub is composed of multiple Java classes, and one of those classes contains a method which corresponds to the webservice method and its arguments. In this example, the stub interface (found in CFusionMX7/stubs/) contains the following method signature:

public String test1(Object a1, Object a2)

Under the hood, the cfinvoke consumer syntax with just one cfinvokeargument subtag (omitting the optional argument) is translated to a Java method call test1(a1), and since a Java method is partly defined by the arguments that it takes the JVM then throws an exception because the method signature is actually test1(Object a1, Object a2) not test1(Object a1). Hence, the ServiceMethodNotFoundException.

The solution for this problem was introduced in ColdFusion MX 7.0 with an optional attribute omit="(yes|no)" for the cfiinvokeargument tag. When calling the example webservice and passing the required argument a1 only then you must use a <cfinvokeargument name="a2" omit="yes"> without a value to properly invoke the webservice. Effectively, this causes ColdFusion to make the Java method call test1(a1, a2) where a2 is null, and this matches the the method signature test1(Object a1, Object a2).

The CFML invocation could include some logic to determine how to properly call the webservice under the conditions where optional arguments may not be sent:

Webservice Consumer (Corrected Typical Syntax)

<cfset variables.arg1 = 1>
<!--- cfset variables.arg2 = 2> --->

<cfinvoke webservice="http://localhost/webservice_optargs.cfc?wsdl" returnvariable="result" method="test1">
<cfinvokeargument name="a1" value="#variables.arg1#">
<cfif isdefined("variables.arg2")>
<cfinvokeargument name="a2" value="#variables.arg2#">
<cfelse>
<cfinvokeargument name="a2" omit="yes">
</cfif>
</cfinvoke>

Unfortunately, the syntax to pass optional arguments as nulls does not exist for the tag CFOBJECT or the function createObject().

From the cfinvokeargument documentation:

You can omit a parameter by setting the cfinvokeargument omit attribute to "yes". If the WSDL specifies that the argument is nillable, ColdFusion MX sets the associated argument to null. If the WSDL specifies minoccurs=0, ColdFusion MX omits the argument from the WSDL. However, CFC web services must still specify required="true" for all arguments.

omit Optional attribute, default is "no"

Enables you to omit a parameter when invoking a web service. It is an error to specify omit="yes" if the cfinvoke webservice attribute is not specified. "yes": omit this parameter when invoking a web service. "no": do not omit this parameter when invoking a web service.

 


Comments

Just happened to be dealing with this. Couldnt be more timely. Thanks!


Great stuff! We ran into this a while back and I wish we had known this.

I am wondering though, if you specify a value in the invokeargument and put omit=no, it should still work right? and conversly, if you specify a value and put omit=yes it should also work, but not send the value?


A value + omit=yes will throw a attribute validation error. Otherwise, omit=no is default, so if you add omit=no or you omit omit it will work as normal.


Yes, great stuff, Steven. Thanks for sharing. One of those many hidden gems in CFMX 7 that many of us missed. I even have a talk on CFML web services that I did at CFUnited (and a few other times over the past few years) and I've pointed out this problem. Great to know there is now a solution.


What about with Nested complex types where structures are needed? How can we omit these arguments within a structure?


Thanks again Steven. Great article, helped a lot. We had a CFC we were using internally (not as a webservice), and 'converting' it took a lot longer than expected.

It's amazing debugging some of these issues when you get an error that doesn't make sense... you just have to type the error into Google and start surfing. Your site often appears to be the best destination.


First of all thank you for this great article it was very helpful for my situation.

I have used the omit="yes" to omit the optional items that seemed to work but i'm now receiving a java NullPointers error:

"Could not perform web service invocation "createInteractionSimple".
Here is the fault returned when invoking the web service operation:
java.lang.NullPointerException"

Any help would be greatly appreciated.

Thanks, Jennifer


I'd like to reiterate the question Shane asked: the omit on cfinvokeargument is great--as long as the argument is a top-level one, but if you have a structure to pass in, and one of the keys in the structure is optional, it doesn't seem possible to omit that. Or am I missing something?


 

 

Calendar

 
Sun Mon Tue Wed Thu Fri Sat
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    

Search This Site

 
This is an exact search only

topics

 
adobe blogging coldfusion computer technology events flex java learning linux mac os x macromedia meetup new england odds & ends outdoors personal photos photoshop science travel video

About This Site

 
Adobe Alumni & Community Professional. Expert in ColdFusion, Flex, LCDS, Photoshop, Lightroom. Linux RHCE. Follow Me!. For my photography check out Boston Portrait Photographer.

Speaker at CF.Objective(): Automated UI Testing with CFSelenium, MXUnit, ANT, and JenkinsCI

Adobe Community Professional (ACP)
Red Hat Linux Certified Engineer

Recent Entries

 
Automated System Testing for ..
Could not find ColdFusion com..
No April Fools: Selenium Ship..

Recent Comments

 
Posted By Steven Erat:
Jim, and anyone else that may attend, if you would like the full slide deck and my demo project files BEFORE the conference, please reply as a comment ...

Posted By Jim Priest:
Can't wait for this one!!

Posted By iPhone Repair:
It appears there are so many people have issue with their iPhone & iPod Touch screens dropped and cracked. It happened to me also when u haven't got a ...

recently played

 
Mr. Brightside
by The Killers
on Hot Fuss
Get Hot Fuss by The Killers on Amazon

now playing, a plug-in for itunes

Categories

 
RSS Adobe (34)
RSS Bicycling (9)
RSS Blogging (39)
RSS Books (13)
RSS Breeze (13)
RSS CFMX Podcasts (10)
RSS ColdFusion (437)
RSS Computer Technology (51)
RSS Events (26)
RSS Flex (20)
RSS Gadgets (11)
RSS HiTech Industry (16)
RSS Java (26)
RSS Learning (57)
RSS Linux (70)
RSS Mac OS X (23)
RSS Macromedia (27)
RSS Meetup (35)
RSS New England (62)
RSS Odds & Ends (25)
RSS Outdoors (32)
RSS Personal (29)
RSS Photos (111)
RSS Photoshop (29)
RSS Podcasts (18)
RSS Rants (19)
RSS Restaurants (8)
RSS Science (34)
RSS Spain (16)
RSS Travel (42)
RSS Twitter (10)
RSS Video (20)
RSS Webcam (3)
RSS Writing (10)

RSS

 


Add to Google
Add to My Yahoo!

Credits and Stuff

 
BlogCFC - Free ColdFusion Powered Blog Software


 
 
blog | photos | flickr | referers | webcam | stats | about | contact
 
Copyright © 2012 Steven Erat. All rights reserved.
This is a personal weblog. The opinions expressed here represent my own and not those of my employer