Steven Erat's Blog
 
 
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


 

 

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        

Search This Site

 
This is an exact search only

About This Site

 
I live west of Boston and work for Adobe with ColdFusion and Flex, and specialize in Linux. I'm also interested in travel and science, and I'm studyng photography at CDIA. Curious about my banner image?

More about me

Recent Entries

 
Hollywood East comes to Bosto..

Recent Comments

 
Posted By Jennifer:
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 se ...

Posted By Mark Lynch:
Thanks for the tips. I found another issue relating to MYSQL autoconfiguration which I've documented here: [link] Thanks, Mark ...

Posted By Quinn:
even when a cert is imported to the keystore, it looks like coldfusion does not support the "Subject Alternative Name" extension of the cert. i've ...

recently played

 
Episode 18 - StackOverflow
by Jeff Atwood and Joel Spolsky
on IT Conversations
IT Conversations, Jeff Atwood and Joel Spolsky

now playing, a plug-in for itunes

Categories

 
RSS Adobe (29)
RSS Bicycling (9)
RSS Blogging (37)
RSS Books (13)
RSS Breeze (12)
RSS CFMX Podcasts (10)
RSS ColdFusion (417)
RSS Computer Technology (49)
RSS Events (25)
RSS Flash (3)
RSS Flex (17)
RSS Gadgets (10)
RSS HiTech Industry (16)
RSS Java (25)
RSS Learning (54)
RSS Linux (70)
RSS Mac OS X (21)
RSS Macromedia (28)
RSS Meetup (34)
RSS New England (60)
RSS Odds & Ends (25)
RSS Outdoors (32)
RSS Personal (26)
RSS Photography (105)
RSS Photoshop (28)
RSS Podcasts (18)
RSS Rants (19)
RSS Restaurants (8)
RSS Science (34)
RSS Spain (16)
RSS Travel (42)
RSS Video (20)
RSS Webcam (3)
RSS Writing (10)

Blogs I Read

 
Scrum Sucks
Ben Forta
Ray Camden
Kinky Solutions
Gary Gilbert
Red Hat Blogs
O'Reilly Digital Media
O'Reilly Radar
John Nack
The Strobist
Scott Kelby
Matt Kloskowski
Joe McNally
Digital Photography School
Engadget
Science Blog

RSS

 


Add to Google
Add to My Yahoo!

Aggregated By

 


Consumed By Feed-Squirrel.com
Aggregated by ColdFusionBlogger.org

Credits and Stuff

 
BlogCFC - Free ColdFusion Powered Blog Software
CJM Group - ColdFusion Website Hosting


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