Even though there is a work-around, this is still a bug. When using
document/literal, Axis must generate a response message according to
the structure defined in the schema in the WSDL. It should generate
its own function return value only when using RPC style.
- Anne
On Fri, 07 Jan 2005 17:34:59 +0900, Bill Keese
<[EMAIL PROTECTED]> wrote:
Ah, I see. Yes, you should be able to use document style or wrapped style,
and in document style you don't put the action name inside the soapBody.
I just looked at the AXIS code that serializes the response
(Emitter.getResponseMessage()). It seems like, regardless of the WSDL file,
AXIS serializes your function return value as
<XXXReturn>
12345
</XXXReturn>
where 12345 is the return value, and XXX is supposed to be the operation
name (see the code "retName = oper.getName() + "Return";"). Although in
your case, it's getting confused about what the operation name is. However,
you can override the name of that tag by writing the return information into
the WSDD file. Something like this:
<operation name="reverse" qname="operNS:reverse"
xmlns:operNS="http://ws.moon.net/j2me05"
returnQName="retNS:reverseResult"
xmlns:retNS="http://ws.moon.net/j2me05"
returnType="rtns:string"
xmlns:rtns="http://www.w3.org/2001/XMLSchema" >
<parameter qname="pns:in0" xmlns:pns="http://ws.moon.net/j2me05"
type="tns:string"
xmlns:tns="http://www.w3.org/2001/XMLSchema"/>
</operation>
According to my reading of Emitter.getResponseMessage() that should let you
control the name of the tag immediately below <soap:Body>. Does that work?
Bill
Ephemeris Lappis wrote:
Hello.
I don't think the problem comes from the request format. First,
similar
examples, all in document/literal style works fine with the same
client
(Wireless Toolkit) running against the SUN's JWSDK server. Then, i
suppose
that if the requests were not correct, the axis server should
respond with a
fault, and not serve them with an invalid response. Although
i'm not an
expert, i think the form you give is like a 'wrapped' style
request while
i'm trying to use the 'document' style...
I've tried the two
forms (original and the one you suggested) with a simple
HttpURLConnection,
and wile the first one always produce the successful
invalid response, the
modified one ends with an axis server fault response.
See bellow the test
code...
I'd really like an answer to my bug report from the axis
team...
Thanks anyway...
package my.tests;
import
java.io.BufferedReader;
import java.io.InputStreamReader;
import
java.io.PrintStream;
import java.net.HttpURLConnection;
import
java.net.URL;
public class Test1 {
public static void main(final String[]
args) throws Exception {
StringBuffer sb = new StringBuffer();
sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>").append("\r\n");
sb.append("<soap:Envelope
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"").append("\r\n");
sb.append("xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"").append("\r\n");
sb.append("xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"").append
("\r\n");
sb.append("xmlns:tns=\"http://ws.moon.net/j2me05\">").append("\r\n");
sb.append("<soap:Body>").append("\r\n");
sb.append("<tns:in0>ABC</tns:in0>").append("\r\n");
sb.append("</soap:Body>").append("\r\n");
sb.append("</soap:Envelope>");
call(sb);
sb = new StringBuffer();
sb.append("<?xml version=\"1.0\"
encoding=\"utf-8\"?>").append("\r\n");
sb.append("<soap:Envelope
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"").append("\r\n");
sb.append("xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"").append("\r\n");
sb.append("xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"").append
("\r\n");
sb.append("xmlns:tns=\"http://ws.moon.net/j2me05\">").append("\r\n");
sb.append("<soap:Body>").append("\r\n");
sb.append("<tns:reverse>").append("\r\n");
sb.append("<tns:in0>ABC</tns:in0>").append("\r\n");
sb.append("</tns:reverse>").append("\r\n");
sb.append("</soap:Body>").append("\r\n");
sb.append("</soap:Envelope>");
call(sb);
}
static void call(final StringBuffer sb) throws Exception {
URL url =
""
URL("http://localhost:9999/j2me05ws-ejb/J2ME-05-WS/J2ME05WS");
HttpURLConnection http = (HttpURLConnection) url.openConnection();
http.setRequestMethod("POST");
http.setDoOutput(true);
http.setRequestProperty("Content-Type", "text/xml");
http.setRequestProperty("Content-Length", String.valueOf(sb.length()));
http.setRequestProperty("SOAPAction", "");
PrintStream ps = new
PrintStream(http.getOutputStream());
ps.print(sb);
ps.flush();
BufferedReader reader = new
BufferedReader(new
InputStreamReader(http.getInputStream()));
for (;;) {
String line = reader.readLine();
if (line == null)
break;
System.out.println(line);
}
http.disconnect();
}
}
-----Message d'origine-----
De : Bill Keese
[mailto:[EMAIL PROTECTED]]
Envoyé : vendredi 7 janvier 2005 02:39
À
: [EMAIL PROTECTED]
Objet : Re: Document/Literal : bad part name in
axis server response
OK. I looked over your mail again and I saw a
problem. You are using
document/literal, right? For the request, you should
have the name of
the method within your soap body. And for the response, I'm
not sure
what is correct but I listed my hypothesis below. (I'm still
figuring
it out myself)
Here's the current request:
<soap:Body>
<tns:in0>ABC</tns:in0>
</soap:Body>
</soap:Envelope>
You
are calling the method "reverse" with the parameter "in0",
right? I
think
the SOAP body should be:
<soap:Body>
<reverse>
<in0>ABC</in0>
</reverse>
</soap:Body>
(I'm not sure about the namespaces though)
Here's
the current response
<soapenv:Body>
<in0Return
xmlns="http://ws.moon.net/j2me05">CBA</in0Return>
</soapenv:Body></soapenv:Envelope>
It thinks that in0 is the name of your
method, rather than the name of
the parameter to the method.
To setup the
request, you need a schema type with the same name as your
method:
<schema
xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://ws.moon.net/j2me05"
elementFormDefault="qualified">
<complexType name="reverse">
<element name="in0" type="xsd:string"/>
</complexType>
</schema>
Then you setup a message that just points to the
schema type
(it's useless but you have to put it in because that's the
way
WSDL works):
<wsdl:message name="reverseRequest">
<wsdl:part
name="parameters" element="impl:reverse"/>
</wsdl:message>
I'm not sure
how to setup the WSDL with regard to responses.
If you look at
http://www.n2soft.net/Services/HNDCAP.asmx?wsdl
(or other links from
www.mindreef.com), you will see this:
<s:element name="PostScoreResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1"
maxOccurs="1"
name="PostScoreResult" type="s:boolean"/>
</s:sequence>
</s:complexType>
</s:element>
<wsdl:message name="PostScoreSoapOut">
<wsdl:part name="parameters"
element="tns:PostScoreResponse"/>
</wsdl:message>
(Again, the message just
points to the schema definition, where
the element name is methodName +
"Response".
I guess that this would produce a response like
<soap:Body>
<PostScoreResponse>
<PostScoreResult>42</PostScoreResult>
</PostScoreResponse>
</soap:Body>
It seems like a lot of overhead for one
number but I've got a
feeling that the clients won't work unless you
structure it
like that. I'm still experimenting though.
Bill
Ephemeris
Lappis wrote:
Before i open a bug, i'd like to have the opinion of experts !
All my last
tests around document/literal style let me with
troubles. To
start again with simple things, i have made a basic service to
evaluate
the
primary interoperability with my J2ME client. This simple
service provides
a
single operation that takes a string, reverses it and return it.
On the
client side, i work with the SUN Wireless toolkit that
support the
JSR172 (web-service for J2ME). Using the axis wsdl i have
successfully
generated the j2me client stubs, and built my midlet to call
the web
service. At run time, the client reports an error in the
server
response :
the name of the response part for the return value is not as
defined in
the
wsdl descriptor. To be sure, i had made the test again putting the
tcp
monitor in the middle... and it seems the client is right !
The name of
the part in the wsdl is 'reverseReturn' and axis uses
'in0Return'...
Is it a
bug, or just another mis-interpretation of mine ?
Thanks to give your
opinion before i open an unnecessary bug report...
Here the java code
:
--- java interface ---
package net.moon.me.five.ws;
import
java.rmi.Remote;
import java.rmi.RemoteException;
public interface
StringTool extends Remote {
public String reverse(String string) throws
RemoteException;
}
----------------------
I have successfully generated
the wsdl with the following ant script :
--- wsdl2java ant script
---
<property name="my.namespace" value="http://ws.moon.net/j2me05"
/>
<java2wsdl output="./wsdl/j2me05ws.wsdl"
className="net.moon.me.five.ws.StringTool"
namespace="${my.namespace}"
porttypename="StringUtility"
serviceportname="StringUtilityPort"
serviceelementname="J2ME05"
style="DOCUMENT"
location="http://ws.moon.net/j2me05">
<classpath>
<pathelement
location="${my.services.compile-directory}" />
<path
refid="my.axis.classpath" />
</classpath>
</java2wsdl>
----------------------------
The resulting WSDL,
with the expected part names !
--- WSDL ---
<?xml version="1.0"
encoding="UTF-8"?>
<wsdl:definitions
targetNamespace="http://ws.moon.net/j2me05"
xmlns:impl="http://ws.moon.net/j2me05"
xmlns:intf="http://ws.moon.net/j2me05"
xmlns:apachesoap="http://xml.apache.org/xml-soap"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<!--WSDL
created by Apache Axis version: 1.2RC2
Built on Nov 16, 2004 (12:19:44
EST)-->
<wsdl:types>
<schema
xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://ws.moon.net/j2me05"
elementFormDefault="qualified">
<element name="in0" type="xsd:string"/>
<element name="reverseReturn"
type="xsd:string"/>
</schema>
</wsdl:types>
<wsdl:message
name="reverseRequest">
<wsdl:part name="in0" element="impl:in0"/>
</wsdl:message>
<wsdl:message name="reverseResponse">
<wsdl:part
name="reverseReturn" element="impl:reverseReturn"/>
</wsdl:message>
<wsdl:portType name="StringUtility">
<wsdl:operation name="reverse"
parameterOrder="in0">
<wsdl:input name="reverseRequest"
message="impl:reverseRequest"/>
<wsdl:output name="reverseResponse"
message="impl:reverseResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding
name="StringUtilityPortSoapBinding"
type="impl:StringUtility">
<wsdlsoap:binding
style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="reverse">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="reverseRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="reverseResponse">
<wsdlsoap:body
use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="J2ME05">
<wsdl:port
name="StringUtilityPort"
binding="impl:StringUtilityPortSoapBinding">
<wsdlsoap:address location="http://ws.moon.net/j2me05"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
-------------------------------------
And
now, the dumped http request and response :
--- request ---
POST
/j2me05ws-ejb/J2ME-05-WS/J2ME05WS HTTP/1.1
User-Agent: Profile/MIDP-1.0
Configuration/CLDC-1.0
Content-Language: en-US
Content-Type:
text/xml
SOAPAction: "
Content-Length: 315
Host: localhost
<?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/"
xmlns:tns="http://ws.moon.net/j2me05">
<soap:Body>
<tns:in0>ABC</tns:in0>
</soap:Body>
</soap:Envelope>
---------------
--- response ---
HTTP/1.1 200
OK
Set-Cookie: JSESSIONID=75C329A6CED0EE74D896E083043AFA0A;
Path=/j2me05ws-ejb
Content-Type: text/xml;charset=utf-8
Transfer-Encoding: chunked
Date: Tue,
21 Dec 2004 14:15:18 GMT
Server: Apache-Coyote/1.1
123
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<in0Return
xmlns="http://ws.moon.net/j2me05">CBA</in0Return>
</soapenv:Body></soapenv:Envelope>
0
----------------