Posts Tagged ‘WSDL Message Part’

Tips and Tricks to use SOAP Webservice with Flex

Thursday, August 12th, 2010

At the moment, I’m working on project where we are using SOAP Webservices to connect the SAP Backend with the Flex Frontend. Before I joined the project, they used a e4x to parse the SOAP Webservice responses. I switched the implementation to use as reponse type object instead of E4X or XML. This switch brings advantages and disadvantages.

Out of the box the Flex soap decoder can handle all objects which are of any type defined be the XSD Schema( string, date, int, boolean…). If your webservice contains ComplexType Objects, you have to define a mapping between the XML structure coming back from the webservice and corresponding ActionScript3 Object. This can be done by using the SchemaTypeRegistry, where you have register your custom classes and collections.

SchemaTypeRegistry.getInstance().registerClass(new QName("http://www.example.com","MyClass"),com.example.MyClass);
SchemaTypeRegistry.getInstance().registerCollectionClass(new QName("http://www.example.com","MyCollection"),com.example.MyCollection);

I recommand to add this stuff to SchemaTypeRegistry after the WSDL of webservice was loaded.

Sometimes registration solves not all the decoding problems, that can happen if the WSDL contains Message Parts. In this case, the top level/root object of webservice response will not decoded properly and returns an untype object. To solve this issue, you have to change some parameters of the interface ISOAPDecoder, which is implemented by the decoder of the webservice operation.

var searchResponseMessage:WSDLMessage=new WSDLMessage("itemSearchResponse");
searchResponseMessage.addPart(new WSDLMessagePart(new QName("http://www.example.com", "itemSearchResponse"), null, new QName("http://www.example.com", "ItemSearchResponse")));
searchResponseMessage.encoding=new WSDLEncoding();
searchResponseMessage.encoding.namespaceURI="http://www.example.com";
searchResponseMessage.encoding.useStyle="literal";
var searchOperation:Operation=myWebservice.getOperation("FindItem") as Operation;
searchOperation.decoder.wsdlOperation.outputMessage=searchResponseMessage;
searchOperation.decoder.resultFormat="object";
searchOperation.decoder.headerFormat="object";
searchOperation.decoder.multiplePartsFormat="object";
searchOperation.decoder.forcePartArrays=false;

This can changes can only applied when the WSDL was successful loaded, otherwhise the step will fail with a NullPointerException.

To get all the necessary information to apply this changes is a little bit tricky if you want to do it manually. I’m using the “Import Web Service (WSDL)” function of Flex Builder 3 to get the information and simply copy and paste them into my project. If your webservice has the name “SearchService” then the importer generates an ActionScript File with the name “BaseSearchService”. You can find all information for your changes in that file.

An other benefit of the importer is the generation of the corresponding ActionScript Class, which speeds up the development of the Flex application when you’re using webservice. Replacing of an complete webservice can be done in a couple minutes.

Now, you asking yourself why I’m not directly using the generated service and classes of the importer. This is a good question. I’m not really liking the code of the generated classes, it creates a wrapper based on an AbstractedWebservice and it isn’t as easy to apply any changes on it. Also if you are working with MVC frameworks like Cairngorm or PureMVC, the wrapper isn’t a valid solution. These frameworks are using Responders and AsyncTokens to handle server responses, but the wrappers are only providing EventListeners and that fits not really together.

The disadvantage of using SchemaType mapping to decode your webservice calls is speed of the decoding. The decoding via SchemaType can take multiple seconds whereas the parsing of the webservice response via E4X or XML needs only a few milliseconds.

James Ward from Adobe provides a small application, which visualize the speed difference between E4X and SchemaType.

My recommandation is to use SchemaType mapping in the early stage of the project or in projects where the webservice will be changed a lot during the development. It’s easier to update the SchemaType mapping and you can’t forgot to map something like you will do if you create your custom mapping with E4X, trust me. 😉

Development Speed vs. Application Speed

Now, you only have decide if you want to exchange the parsing of your webservice before releasing your application. The parsing of the webservice response with a custom mapping based on EX4 is lot faster than SchemaType and users hate nothing more than applications that are slow.