Why would same SOAP request work in one Flex project and not another?
This is a pretty odd situation I have here. I have used a piece of code to interact with a backend SOAP service for several months - it works fine. I tried it out in a different project (first as an swc library and then just by cutting and pasting) and it just doesnt work.
If I try the exact same code in the original flex project, connecting to the same backend service, everything works fine. In the new project, I can call operations that take simple document-literal wrappers as params (they have no real parameters) - but if the operation has a complex parameter inside the document literal wrapper - fail on this new project. Here is a sample that would fail:
var service:WebService = new WebService();
service.wsdl = wsdlURL;
var operation:AbstractOperation = service.getOperation( "addNewUser" );
var param:XML = <AddNewUserRequest/>
param.setNamespace( myNameSpace );
param.user.username( username );
param.user.email( email );
operation.send( param );
And here is a sample that would work in the new project:
var service:WebService = new WebService();
service.wsdl = wsdlURL;
var operation:AbstractOperation = service.getOperation( "getUsers" );
var param:XML = <GetUsersRequest/>
param.setNamespace( myNameSpace );
operation.send( param );
Here are some things that I have done to try an track this one down:
-Examined the posts in firebug from both projects and can not see a difference (meaning that the code appears to generate the exact same SOAP request in both projects (as one expects) -I have verified that the requests should work using SOAPui to directly 开发者_运维问答query the web service
The back end service is an Apache CXF webservice and here is a sample of the error it generates:
org.apache.cxf.interceptor.Fault: Found element {http://www.w3.org/2001/XMLSchema}user but could not find matching RPC/Literal part
Everything I know leads me to believe that user should be in the http://www.w3.org/2001/XMLSchema namespace - and honestly - I believe the key here is that the code works in one project but not in the other. Could it be an XML setting? One of the static ones like ignoreWhitespace? I have played with changing those around - with no luck.
Any ideas at all? This is driving me crazy!!!
UPDATE:
I have narrowed it down to this: the new project creates a header like this:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
and the one that works creates this:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
Why the difference on the exact same version of flex & flex builder? The one that works is obviously correct (xmlns:xsd="http://www.w3.org/2001/XMLSchema") - the web service is correct to reject a request that puts everything in the request in the xsd namespace.
The reason it's adding xmlns="http://www.w3.org/2001/XMLSchema"
to the SOAP Envelope instead of xmlns:xsd="http://www.w3.org/2001/XMLSchema"
is because that's how it's defined in rpc.xml.SchemaConstants class. At some point in the broken project, you have imported an xsd into the rpc.xml.SchemaManager class that defines xmlns="http://www.w3.org/2001/XMLSchema"
, which overrides the default definition in SchemaConstants.
Try checking all of the xsds that you are using and make sure that they don't contain xmlns="http://www.w3.org/2001/XMLSchema"
.
You're hardcoding your request as XML, and I assume your custom namespace doesn't have a prefix, so it's conflicting with the default namespace for XSD declared in your header. Why you're getting different headers I don't know, but you're probably compiling your project with different versions of the SDK.
A few things to try:
Make sure you're using the sake SDK to compile both projects (the latest you can get away with, as bugfixes to the SOAP stack go into almost every release)
Set an explicit prefix for your namespace, using:
var myNameSpace:NameSpace = new NameSpace("my","http://something.com/foo/ns");
Instead of building an XML request, build it as plain AS3 Objects, like so:
var request:Object = {GetUsersRequest: {parm1: foo, parm2:bar }};
...and let Flex do all the encoding for you. A whole bunch of people (myself included) have put countless hours into making the Flex SOAP stack work well with AS3 objects instead of hand-crafted XML requests, why not let the SDK do the work of constructing your request for you?
精彩评论