I am working with a webservice that provides basic CRUD functionality. The Retrieve is easy enough to work with, but I'm having trouble working with the Create (I've not yet messed with the Update or Delete functions).
The update function takes a single argument. This is a zObject in the WSDL. However, this is 开发者_C百科a generic object extended by what I actually need to pass. If I want to create an account, for example, I pass an Account object which extends the zObject definition.
I cannot for the life of my figure out how to get CF to allow me to do this.
ColdFusion implements the Apache Axis engine for its web service functionality. Unfortunately CF does not take full advantage of the SOAP object model and allow CF developers to "new" the different objects that make up a service (or subclass them).
Thankfully there is something we can do about that. When you first access a WSDL, Axis generates a set of stub objects. These are regular java classes that contain getters and setters for the base properties of the object. We need to use these stubs to build our object.
In order to use these stubs however, we need to add them to the ColdFusion class path:
Step 1) Access the WSDL in any way with coldfusion.
Step 2) Look in the CF app directory for the stubs. They are in a "subs"
directory, organized by WSDL.like:
c:\ColdFusion8\stubs\WS\WS-21028249\com\foo\bar\
Step 3) Copy everything from "com" on down into a new directory that exists in
the CF class path. or we can make one like:
c:\ColdFusion8\MyStubs\com\foo\bar\
Step 4) If you created a new directory add it to the class path.
A, open CF administrator
B. click on Server settings >> Java and JVM
C. add the path to "ColdFusion Class Path". and click submit
D. Restart CF services.
Step 5) Use them like any other java object with <CFObject /> or CreateObject()
MyObj = CreateObject("java","com.foo.bar.MyObject");
Remember that you can CFDump the object to see the available methods.
<cfdump var="#MyObj#" />
Your account object SHOULD be in the stubs. If you need to create it for some reason you would need to do that in a new Java class file
Generally when working with this much Java, cfscript is the way to go.
finally, the code would look like this:
<cfscript>
// create the web service
ArgStruct = StructNew();
ArgStruct.refreshWSDL = True;
ArgStruct.username = 'TestUserAccount';
ArgStruct.password = 'MyP@ssw0r3';
ws = createObject("webservice", "http://localhost/services.asmx?WSDL",ArgStruct);
account = CreateObject("java","com.foo.bar.Account");
account.SetBaz("hello world");
ws.Update(account);
</cfscript>
I agree with the critique of ColdFusion, however, the posted solution also does not respond well to wsdl changes.
Thankfully CF does all access to all the underlying Java methods on objects. This includes 'reflection'. While CreateObject does not know about the stub objects, the classloader that created the webservice does.
ws = createObject("webservice", "http://localhost/services.asmx?WSDL",ArgStruct);
account = ws.getClass().getClassLoader().loadClass('com.foo.bar.Account').newInstance();
精彩评论