Re: "is it always so hard for SOAP interop?" The answer is that it is easy if someone has already done the interop coding. In this case, you are using Apache SOAP as the client. Development of Apache SOAP has mostly stopped, with effort being applied to the "next generation", which is Axis. Interop with the SOAP Toolkit is pretty well understood, since the SOAP Toolkit (version 2.0, at least) was available last Spring while Apache SOAP development was still very active. As .NET got to later betas and people were using it more, Apache SOAP development was less active, and less interop work was done (or at least "published"). Anyway, I better stop now, because I am not an interop expert by any means. I have worked with Apache SOAP, SOAP Toolkit 2 and SOAP::Lite (perl), but that's it.
I think the thing to focus on is the point made by Simon Fell, which I take to ultimately mean that the problem lies in the encodingStyle attribute. When I look at "The SOAPBuilders Interoperability Lab" (http://www.xmethods.net/ilab/) and click the link for the .NET beta 2 client, what strikes me about the wire dumps of the client is that the encodingStyle attribute *is* present, and it is SOAP encoding. I do not know whether this means Microsoft switched the default encoding, or whether for interop testing the .NET client forced the encoding. While I understand you are using a .NET server with an Apache client, the presence of the encodingStyle is interesting nonetheless, and I am wondering whether a small change to your server code would make your .NET server accept messages from Apache SOAP. An excerpt from the .NET interop server code is: namespace Simple { using System; using System.Xml; using System.Web.Services; using System.Web.Services.Protocols; using System.Xml.Serialization; using System.IO; using System.Web; [WebService(Description="These operations implement some simple Section 5, rpc-style SOAP operations, for interop testing. Please email [EMAIL PROTECTED] with any questions.", Namespace="http://soapinterop.org/")] [SoapRpcService(RoutingStyle=SoapServiceRoutingStyle.RequestElement)] public class SimpleTest { [WebMethod] [TraceExtension(Filename=@"C:\interop.log")] [System.Web.Services.Protocols.SoapRpcMethodAttribute("http://soapinterop.or g/", RequestNamespace="http://soapinterop.org/", ResponseNamespace="http://soapinterop.org/")] [return: SoapElement("return")] public string echoString(string inputString) { return inputString; } } Are there any attributes in this code that you do not use? The WSDL for this service is available at http://www.mssoapinterop.org/asmx/simple.asmx?WSDL. This appears to use SOAP encoding. Scott Nichol ----- Original Message ----- From: <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Monday, February 25, 2002 8:07 AM Subject: Re: java client for .NET - what do i ignore ? - GETTING MAD thanks a lot Scott and all of you for your patience... in fact, i made tests, where i hard code the soap message and send it to the .NET webservice, sending him EXACTLY what is expects... and it works but as soon as i generate SOAP with the following code, the soap message changes, using 1999 schema and then .NET doesn't understand the simple string i send. Is there a way to generate the SOAP message "closer" from what . NET is expecting ? i really don't understand why i'm not able to make this java client work... is it always so hard for SOAP interop ? or am I simply stupid ? ;-) It's really serious if i can't even send a correct String ! i thought i could have missed maybe the serialization part of the process... any idea ?? sorry for my coarse English regards, Elise ps : i specified also 2001 schema but the result i get is : Caught SOAPException (SOAP-ENV:Client): No Serializer found to serialize a 'org.apache.soap.rpc.Parameter' using encoding style 'http://www.w3.org/2001/XMLSchema-instance'. what i made : replace Constants.NS_URI_SOAP_ENC by Constants.NS_URI_2001_SCH EMA_XSI, should it be enought ??? i also added on the .NET webservice the SoapRPCService attribute that tells ASP.NET to expose webservice and any exposed web methods as RPC/encoded ======================================= code that works : hard coded StringBuffer payload = new StringBuffer("<?xml version=\'1.0\' encoding=\'UTF-8\'?>"); payload.append("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"); payload.append("<soap:Body>"); payload.append("<Bonjour xmlns=\"http://tempuri.org/\">"); payload.append("<strName>elise</strName>"); payload.append("</Bonjour>"); payload.append("</soap:Body>"); payload.append("</soap:Envelope>\r\n"); URL endpoint = new URL("http://biztalk:8080/PCS_Integration/SynchronizeProfiles.asmx"); URLConnection con = endpoint.openConnection (); con.setDoInput (true); con.setDoOutput (true); con.setUseCaches (false); con.setAllowUserInteraction(false); con.setRequestProperty ("Content-Length", Integer.toString (request.length)); con.setRequestProperty ("Content-Type", "text/xml; charset=utf-8"); con.setRequestProperty ("SOAPAction", "\"http://tempuri.org/Bonjour\""); OutputStream out = con.getOutputStream (); out.write (payload); out.flush (); out.close(); InputStream in = con.getInputStream(); int i= -1; while((i = in.read()) > -1) { System.out.print((char)i); } =============================================== code that doesn't work but MUST work ;-) URL url = new URL ("http://biztalk:8080/PCS_Integration/SynchronizeProfiles.asmx"); SOAPMappingRegistry smr = new SOAPMappingRegistry (); StringDeserializer sd = new StringDeserializer (); smr.mapTypes(Constants.NS_URI_SOAP_ENC ,new QName("http://tempuri.org/","BonjourResult"),null,null,sd); // create the transport and set parameters SOAPHTTPConnection st = new SOAPHTTPConnection(); // build the call. Call call = new Call (); call.setSOAPTransport(st); call.setSOAPMappingRegistry (smr); call.setTargetObjectURI ("http://tempuri.org/"); call.setMethodName("Bonjour"); call.setEncodingStyleURI (Constants.NS_URI_SOAP_ENC); Response resp = call.invoke(_url, METHOD_NAMESPACE + "Bonjour"); Vector params = new Vector(); params.addElement(new Parameter("strName", String.class, "elise", null)); call.setParams(params); Response resp = null; try { resp = call.invoke (url, "http://tempuri.org/Bonjour"); } catch (SOAPException e) { System.err.println("Caught SOAPException (" + e.getFaultCode () + "): " + e.getMessage ()); return; } // check response if (resp != null && !resp.generatedFault()) { Parameter ret = resp.getReturnValue(); Object value = ret.getValue(); System.out.println ("Answer--> " + value); } else { Fault fault = resp.getFault (); System.err.println ("Generated fault: "); System.out.println (" Fault Code = " + fault.getFaultCode()); System.out.println (" Fault String = " + fault.getFaultString()); } ================================================= here is what is expecting .NET POST /PCS_Integration/SynchronizeProfiles.asmx HTTP/1.1 Host: biztalk Content-Type: text/xml; charset=utf-8 Content-Length: length SOAPAction: "http://tempuri.org/Bonjour" <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <Bonjour xmlns="http://tempuri.org/"> <strName>string</strName> </Bonjour> </soap:Body> </soap:Envelope> ================================================= here is what is generated by my bad code <?xml version="1.0" encoding="UTF-8" ?> - <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema"> - <SOAP-ENV:Body> - <ns1:Bonjour xmlns:ns1="http://tempuri.org/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <strName xsi:type="xsd:string">elise</strName> </ns1:Bonjour> </SOAP-ENV:Body> </SOAP-ENV:Envelope> Scott Nichol <[EMAIL PROTECTED]> 02/22/2002 08:41 PM Please respond to soap-dev To: [EMAIL PROTECTED] cc: Subject: Re: java client for .NET - what do i ignore ? I notice that .NET does not specify SOAP-ENV:encodingStyle for either the request or response. This may be what Simon means by "doc/literal", but I am not sure. In Apache SOAP, the encoding style is set on the Call object (call.setEncodingStyleURI), each parameter constructor (the final argument, null in your case) and each mapping for complex types (smr.mapTypes). The value is used both for the attributes placed into XML and to locate the proper serializer or deserializer. Without testing this myself, I would suggest you could try using an empty string for call.setEncodingStyleURI, and add an type mapping for an empty encoding URI: Serializer cleanSer = new Serializer() { public void marshall(String inScopeEncStyle, Class javaType, Object src, Object context, Writer sink, NSStack nsStack, XMLJavaMappingRegistry xjmr, SOAPContext ctx) throws IllegalArgumentException, IOException { nsStack.pushScope(); SoapEncUtils.generateStructureHeader(inScopeEncStyle, javaType, context, sink, nsStack, xjmr); sink.write(Utils.cleanString(src.toString()) + "</" + context + '>'); nsStack.popScope(); } }; smr.mapTypes("", null, String.class, cleanSer, null); call.setEncodingStyleURI(""); Scott Nichol ----- Original Message ----- From: <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Friday, February 22, 2002 11:57 AM Subject: Re: java client for .NET - what do i ignore ? right, i can test it, but how do you specify that you send a doc/literal request ?? shall i change the strange parameter : Constants.NS_URI_SOAP_ENC to something else ?? Simon Fell <[EMAIL PROTECTED]> 02/22/2002 05:53 PM Please respond to soap-dev To: [EMAIL PROTECTED] cc: Subject: Re: java client for .NET - what do i ignore ? That correct for calling MS Toolkit 2.0 services, but not for .NET. .NET by default does doc/literal SOAP, not rpc/encoded, you're sending an rpc/encoded message, which .NET will largely ignore. You need to send a doc/literal request. Not sure how you cook those up with the 2.2 code. Cheers Simon www.pocketsoap.com On Fri, 22 Feb 2002 10:35:36 -0600, in soap you wrote: > >//ADD YOUR OWN DESERIALIZER SINCE THIS IS CALLING A MS SERVER THERE IS > //NO xsi:type attribute returned.... > //Create a new SoapMappingRegistry >SOAPMappingRegistry smr = new SOAPMappingRegistry(); > >//Assuming that your return is a string >StringDeserializer ds = new StringDeserializer(); > >//Map the datatype to the name provided.. > smr.mapTypes(Constants.NS_URI_SOAP_ENC,new QName("","BonjourResult >"),null,null,ds); > > //Set the mapping to the call object > call.setSOAPMappingRegistry(smr); > >hth >Doug > > > > Elise_Dupont@lion > bridge.com To: [EMAIL PROTECTED] > cc: (bcc: Doug Swanson/US-Corporate/3M/US) > 02/22/2002 10:24 Subject: Re: java client for .NET - what do i ignore ? > AM > Please respond to > soap-dev > > > > > > > >(i must specify that i read the SOAP documentation about xsi:type problem, >adapted my code to this problem and had no more results....) >the guiden sample didn't help me, and i still have an error when >retrieving the String from .NET webservice > > > >"Caught SOAPException (SOAP-ENV:Client): No Deserializer found to >deserialize a 'http://tempuri.org/:BonjourResult' using encoding style >'http://schemas.xmlsoap.org/soap/encoding/'." > > > > > > > > >[EMAIL PROTECTED] >02/22/2002 11:54 AM >Please respond to soap-dev > > > To: [EMAIL PROTECTED] > cc: > Subject: java client for .NET - what do i ignore ? > > > > >hi, >i'm still making connection tests from my java client to my .NET >webservice. > >i looked at the samples some of you gave me(Scott Nichol with >samples/interop subdirectory of your Apache SOAP >installation) , and other one, the aim was to make a Call() to my .NET >webservice. >I also used a sniffer to look at the soap envelope i'm sending. >First of all, the .NET webservice is expecting SOAP data A (see enclosed >code) but my java client is sending SOAP data B with java client code C, >and as the webservice should return "hello [theString i sent], the result >is simply : > >"EndpointURL: http://biztalk:8080/PCS_Integration/SynchronizeProfiles.asmx >Calling EchoString... >EchoByte called with: [B@171afc >EchoByte Result: Hello" > > > >And then i get this error if i use the code D in my java client : > >"Caught SOAPException (SOAP-ENV:Client): No Deserializer found to >deserialize a 'http://tempuri.org/:BonjourResult' using encoding style >'http://schemas.xmlsoap.org/soap/encoding/'." > > > >what's wrong ? why can't i still have a correct working connection with a >correct understandable data ? Any code i test doesn't fully work... > >any help would be appreciated, as this is just a test part, and i will >have to send a complex data later... I'll never see the end ;) >Elise > > >================================================== >code A : what is expecting .NET > >POST /PCS_Integration/SynchronizeProfiles.asmx HTTP/1.1 >Host: biztalk >Content-Type: text/xml; charset=utf-8 >Content-Length: length >SOAPAction: "http://tempuri.org/Bonjour" > ><?xml version="1.0" encoding="utf-8"?> ><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap=" >http://schemas.xmlsoap.org/soap/envelope/"> > <soap:Body> > <Bonjour xmlns="http://tempuri.org/"> > <strName>string</strName> > </Bonjour> > </soap:Body> ></soap:Envelope> > > >======================================================= >code B : what is sending my java client > ><?xml version="1.0" encoding="UTF-8" ?> >- <SOAP-ENV:Envelope xmlns:SOAP-ENV=" >http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi=" >http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd=" >http://www.w3.org/1999/XMLSchema"> >- <SOAP-ENV:Body> >- <ns1:Bonjour xmlns:ns1="http://tempuri.org/" SOAP-ENV:encodingStyle=" >http://schemas.xmlsoap.org/soap/encoding/"> > <strName xsi:type="xsd:string">my string</strName> > </ns1:Bonjour> > </SOAP-ENV:Body> ></SOAP-ENV:Envelope> > > >================================================================ >Code C : the corresponding java code > > > URL url = new URL (" >http://biztalk:8080/PCS_Integration/SynchronizeProfiles.asmx"); > > SOAPMappingRegistry smr = new SOAPMappingRegistry (); > StringDeserializer sd = new StringDeserializer (); > smr.mapTypes (Constants.NS_URI_SOAP_ENC, new QName ("", >"Result"), null, null, sd); > > // create the transport and set parameters > SOAPHTTPConnection st = new SOAPHTTPConnection(); > > // build the call. > Call call = new Call (); > call.setSOAPTransport(st); > call.setSOAPMappingRegistry (smr); > > call.setTargetObjectURI ("http://tempuri.org/"); > call.setMethodName("Bonjour"); > call.setEncodingStyleURI (Constants.NS_URI_SOAP_ENC); > > Vector params = new Vector(); > > params.addElement(new Parameter("strName", String.class, >"my string", null)); > call.setParams(params); > > Response resp = null; > try { > resp = call.invoke (url, "http://tempuri.org/Bonjour"); > } > catch (SOAPException e) { > System.err.println("Caught SOAPException (" + >e.getFaultCode () + "): " + e.getMessage ()); > return; > } > > // check response > if (resp != null && !resp.generatedFault()) { > Parameter ret = resp.getReturnValue(); > Object value = ret.getValue(); > > System.out.println ("Answer--> " + value); > } > else { > Fault fault = resp.getFault (); > System.err.println ("Generated fault: "); > System.out.println (" Fault Code = " + >fault.getFaultCode()); > System.out.println (" Fault String = " + >fault.getFaultString()); > } > > > > > >================================================================ >code D : The java code that returns me the SOAPException (SOAP-ENV:Client) > > String sEndpointURL = " >http://biztalk:8080/PCS_Integration/SynchronizeProfiles.asmx"; > System.out.println("EndpointURL: " + sEndpointURL); > SynchronizeProfilesProxy profileProxy = new >SynchronizeProfilesProxy(sEndpointURL); > > String theString = "This is a string"; > System.out.println("\nCalling EchoString..."); > System.out.println("EchoByte called with: " + request); > System.out.println("EchoByte Result: " + >profileProxy.EchoByte(request)); > > // This Method uses the "RPC" style of call, and corresponding >Apache 2.2 > // classes to do so. > public synchronized String EchoByte (byte[] theByte) > throws SOAPException > { > if (_url == null) > { > throw new >SOAPException(org.apache.soap.Constants.FAULT_CODE_CLIENT, > "A URL must be specified via setEndPoint(URL)."); > } > > // Map the types. > SOAPMappingRegistry smr = new SOAPMappingRegistry(); > StringDeserializer ser = new StringDeserializer (); > smr.mapTypes (Constants.NS_URI_SOAP_ENC,null, >String.class, null, ser); > _call.setSOAPMappingRegistry(smr); > _call.setMethodName("Bonjour"); > _call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); > Vector params = new Vector(); > Parameter pTheByte = new Parameter("strName", >String.class, "my string", null); > params.addElement(pTheByte); > _call.setParams(params); > Response resp = _call.invoke(_url, METHOD_NAMESPACE + >"Bonjour"); > > // Check the response. > if (resp.generatedFault()) > { > Fault fault = resp.getFault(); > throw new SOAPException(fault.getFaultCode(), >fault.getFaultString()); > } > else > { > Parameter retValue = resp.getReturnValue(); > String theResult = (String)retValue.getValue(); > return theResult; > } > } > > > > ><< File att1.htm not included with reply >> > > >