I'm pretty happy with the (free!) WST plugin for eclipse. XMLSpy is a little more whiz-bang and does a lot of other nice XML stuff, too, but the eclipse plugin caught at least one real error that XMLSpy missed (and my gSOAP customers will never know of my sins.) Mindreef also has a tool that incorporates the WS-I test suite: it catches some things XMLSpy does not and sometimes provides more intelligible error messages for things XML Spy *does* catch.
Chris Eclipse plugin (for eclipse 3.1+) http://update.eclipse.org/updates/3.1 (look for the WST package) Mindreef SOAPScope: http://www.mindreef.com -----Original Message----- From: Bell, Douglas [mailto:[EMAIL PROTECTED] Sent: Thursday, October 27, 2005 15:36 To: [email protected] Subject: RE: Odd nesting when using arrays Best tool I've found for testing interoperability is XMLSpy (http://www.altova.com/products_ide.html). If it works with XMLSpy it's likely to work with any other client. - Doug ________________________________ From: Anne Thomas Manes [mailto:[EMAIL PROTECTED] Sent: Thursday, October 27, 2005 3:20 PM To: [email protected] Subject: Re: Odd nesting when using arrays For better interoperability, switch to doc/literal wrapped style and define your schema yourself rather than generating it from Java. Anne On 10/27/05, todd runstein <[EMAIL PROTECTED]> wrote: I'm concerned that using an array of objects creates a service that is too "axis specific". Or, perhaps I'm not creating my service correctly. In either case, any information or suggestions on the following would be greatly appreciated. Consider this simple service. A Parent class contains an array of Child objects. Given this class, I would expect the client to create a message that looks like: <soapenv:Body> <combinedAges xmlns="Family.Service"> <parent xmlns=""> <children> <age>4</age> </children> <children> <age>5</age> </children> ...... But the client instead generates this (notice how the children tags are nested in a children tag): <soapenv:Body> <combinedAges xmlns="Family.Service"> <parent xmlns=""> <children> <children> <age>4</age> </children> <children> <age>5</age> </children> ...... </children> While both my axis client and service understand this, I'm concerned that non-axis clients won't work. Are my concerns unfounded? Or is this happening because I haven't built or defined the service correctly? I'm including the wsdl, the wsdd, code, request and response. Sorry if this is too much - I'd rather be complete than leave out an important detail. WSDL: - <wsdl:definitions targetNamespace="http://localhost:8080/bc_webservice/services/FamilyServ ice "> - <!-- WSDL created by Apache Axis version: 1.2.1 Built on Oct 27, 2005 (09:15:57 EDT) --> - <wsdl:types> - <schema targetNamespace="urn:FamilyService"> <import namespace="http://localhost:8080/bc_webservice/services/FamilyService"/> <import namespace=" http://schemas.xmlsoap.org/soap/encoding/"/ <http://schemas.xmlsoap.org/soap/encoding/"/> > - <complexType name="Child"> - <sequence> <element name="age" type="xsd:int"/> </sequence> </complexType> - <complexType name="Parent"> - <sequence> <element name="children" nillable="true" type="impl:ArrayOf_tns1_Child"/> <element name="name" nillable="true" type="xsd:string"/> </sequence> </complexType> </schema> - <schema targetNamespace=" http://localhost:8080/bc_webservice/services/FamilyService <http://localhost:8080/bc_webservice/services/FamilyService> "> <import namespace="urn:FamilyService"/> <import namespace=" http://schemas.xmlsoap.org/soap/encoding/"/ <http://schemas.xmlsoap.org/soap/encoding/"/> > - <complexType name="ArrayOf_tns1_Child"> - <complexContent> - <restriction base="soapenc:Array"> <attribute ref="soapenc:arrayType" wsdl:arrayType="tns1:Child[]"/> </restriction> </complexContent> </complexType> </schema> </wsdl:types> - <wsdl:message name="combinedAgesRequest"> <wsdl:part name="parent" type="tns1:Parent"/> </wsdl:message> - <wsdl:message name="combinedAgesResponse"> <wsdl:part name="combinedAgesReturn" type="xsd:int"/> </wsdl:message> - <wsdl:portType name="FamilyService"> - <wsdl:operation name="combinedAges" parameterOrder="parent"> <wsdl:input message="impl:combinedAgesRequest" name="combinedAgesRequest"/> <wsdl:output message="impl:combinedAgesResponse" name="combinedAgesResponse"/> </wsdl:operation> </wsdl:portType> - <wsdl:binding name="FamilyServiceSoapBinding" type="impl:FamilyService"> <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> - <wsdl:operation name="combinedAges"> <wsdlsoap:operation soapAction=""/> - <wsdl:input name="combinedAgesRequest"> <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://webservices.msei.com" use="encoded"/> </wsdl:input> - <wsdl:output name="combinedAgesResponse"> <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace=" http://localhost:8080/bc_webservice/services/FamilyService <http://localhost:8080/bc_webservice/services/FamilyService> " use="encoded"/> </wsdl:output> </wsdl:operation> </wsdl:binding> - <wsdl:service name="FamilyServiceService"> - <wsdl:port binding="impl:FamilyServiceSoapBinding" name="FamilyService"> <wsdlsoap:address location=" http://localhost:8080/bc_webservice/services/FamilyService"/ <http://localhost:8080/bc_webservice/services/FamilyService"/> > </wsdl:port> </wsdl:service> </wsdl:definitions> WSDD: <service name="FamilyService" provider="java:RPC"> <parameter name="allowedMethods" value="*" /> <parameter name="className" value="com.msei.webservices.FamilyService" /> <beanMapping qname="ns:Child" xmlns:ns="urn:FamilyService" languageSpecificType="java:com.msei.webservices.typemapping.Child" /> <beanMapping qname="ns:Parent" xmlns:ns="urn:FamilyService" languageSpecificType="java:com.msei.webservices.typemapping.Parent" /> </service> CODE - Service: public class Parent { private String name; private Child[] children; ...standard bean... } public class Child{ private int age; ...standard bean... } public class FamilyService{ public Integer combinedAges(Parent parent){ int retVal = 0; Child[] children = parent.getChildren(); if (children!=null){ for(int x=0;x<children.length;x++){ retVal += children[x].getAge(); } } return new Integer(retVal); } } CODE - Client: public class FamilyClient{ public static void main(String[] args){ try { String endpointURL = options.getURL (); endpointURL = "http://localhost:5555/bc_webservice/services/FamilyService"; Parent parent = new Parent(); parent.setName("Big Daddy"); Child joey = new Child(); joey.setAge(4); Child suzie = new Child(); suzie.setAge(5); Child stevie = new Child(); stevie.setAge(7); parent.setChildren(new Child[]{joey,suzie,stevie}); Service service = new Service(); Call call = (Call) service.createCall(); QName soapns = new QName("TheFamily","Family.Service"); call.setTargetEndpointAddress( new java.net.URL(endpointURL) ); call.setOperation(soapns, new QName("Family.Service", "combinedAges") ); call.setProperty(Call.SEND_TYPE_ATTR,Boolean.FALSE); call.setOperationStyle(Style.WRAPPED ); QName pName = new QName("urn:Family","parent"); call.registerTypeMapping(Parent.class,pName, new BeanSerializerFactory(Parent.class,pName), new BeanDeserializerFactory(Parent.class,pName)); QName cName = new QName("urn:Family","children"); call.registerTypeMapping(Child.class,cName, new BeanSerializerFactory(Child.class,cName), new BeanDeserializerFactory(Child.class,cName)); call.addParameter("parent",pName,ParameterMode.IN); call.setReturnType(org.apache.axis.encoding.XMLType.XSD_INT ); Integer ret = (Integer) call.invoke( new Object[] { parent } ); System.out.println("Returned : " + ret); } catch (Exception e) { System.err.println (e.toString()); } } } REQUEST: <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv=" http://schemas.xmlsoap.org/soap/envelope/ <http://schemas.xmlsoap.org/soap/envelope/> " xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance <http://www.w3.org/2001/XMLSchema-instance> "> <soapenv:Body> <combinedAges xmlns="Family.Service"> <parent xmlns=""> <children> <children> <age>4</age> </children> <children> <age>5</age> </children> <children> <age>7</age> </children> </children> <name>Big Daddy</name> </parent> </combinedAges> </soapenv:Body> </soapenv:Envelope> RESPONSE: <?xml version="1.0" encoding="utf-8"?> <soapenv:Envelope xmlns:soapenv=" http://schemas.xmlsoap.org/soap/envelope/ <http://schemas.xmlsoap.org/soap/envelope/> " xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance <http://www.w3.org/2001/XMLSchema-instance> "> <soapenv:Body> <ns1:combinedAgesResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/ " xmlns:ns1="Family.Service"> <combinedAgesReturn xsi:type="xsd:int">16</combinedAgesReturn> </ns1:combinedAgesResponse> </soapenv:Body> </soapenv:Envelope> The only "dumb question" is the one you were too afraid to ask. ________________________________________ Check out RouteRuler - Free software for runners, cyclists, walkers, etc. http://routeruler.sourceforge.net ________________________________________ Get a handle on your data with "pocOLAP", the "little" OLAP project http://pocolap.sourceforge.net ________________________________________ __________________________________ Yahoo! FareChase: Search multiple travel sites in one click. http://farechase.yahoo.com
