J
junk
Im having a play with WebServices using IBM RAD 6 as my IDE.
I can get webservices to work ok when the message is a wrapper
containing Strings, ints, and arrays of Strings or ints, but as soon
as I try to use an array of complex types it fails.
The way it fails is that it says the array is an array of
'xsd:anyType' whereas I would expect something like 'impl:mytype'
where mytype would then have 'complexType' entry which would explain
that its just a String and an Int (for example)
Can anyone tell me how I should structure a message object to contain
arrays of wrapper classes? - or any neat tricks to avoid needing
arrays of wrapper classes.
Many Thanks
David Bevan
http://www.davidbevan.co.uk
Heres some wsdl....
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://
helloworld.services.jjs.xxxxxxxxx.com" xmlns:impl="http://
helloworld.services.jjs.xxxxxxxxx.com" xmlns:intf="http://
helloworld.services.jjs.xxxxxxxxx.com" xmlns:wsdl="http://
schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/
wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<wsdl:types>
<schema targetNamespace="http://
helloworld.services.jjs.xxxxxxxxx.com" xmlns="http://www.w3.org/2001/
XMLSchema" xmlns:impl="http://helloworld.services.jjs.xxxxxxxxx.com"
xmlns:intf="http://helloworld.services.jjs.xxxxxxxxx.com"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://
www.w3.org/2001/XMLSchema">
<complexType name="HelloWorld8Msg">
<complexContent>
<extension base="impl:AbstractHelloWorld8Msg">
<sequence>
<element name="name" nillable="true" type="xsd:string"/>
</sequence>
</extension>
</complexContent>
</complexType>
<complexType name="AbstractHelloWorld8Msg">
<sequence>
<element maxOccurs="unbounded" name="myArray" nillable="true"
type="xsd:string"/>
</sequence>
</complexType>
<element name="HelloWorld8Msg" nillable="true"
type="impl:HelloWorld8Msg"/>
<complexType name="HelloWorld8OutMsg">
<complexContent>
<extension base="impl:AbstractHelloWorld8OutMsg">
<sequence>
<element name="name" nillable="true" type="xsd:string"/>
</sequence>
</extension>
</complexContent>
</complexType>
<complexType name="AbstractHelloWorld8OutMsg">
<sequence>
<element maxOccurs="unbounded" name="myArray" nillable="true"
type="xsd:anyType"/>
</sequence>
</complexType>
<element name="HelloWorld8OutMsg" nillable="true"
type="impl:HelloWorld8OutMsg"/>
</schema>
</wsdl:types>
<wsdl:message name="helloWorldResponse">
<wsdlart name="helloWorldReturn" type="impl:HelloWorld8OutMsg"/
</wsdl:message>
<wsdl:message name="helloWorldRequest">
<wsdlart name="aMsg" type="impl:HelloWorld8Msg"/>
</wsdl:message>
<wsdlortType name="HelloWorld8">
<wsdlperation name="helloWorld" parameterOrder="aMsg">
<wsdl:input message="impl:helloWorldRequest"
name="helloWorldRequest"/>
<wsdlutput message="impl:helloWorldResponse"
name="helloWorldResponse"/>
</wsdlperation>
</wsdlortType>
<wsdl:binding name="HelloWorld8SoapBinding"
type="impl:HelloWorld8">
<wsdlsoap:binding style="rpc" transport="http://
schemas.xmlsoap.org/soap/http"/>
<wsdlperation name="helloWorld">
<wsdlsoapperation soapAction=""/>
<wsdl:input name="helloWorldRequest">
<wsdlsoap:body namespace="http://
helloworld.services.jjs.xxxxxxxxx.com" use="literal"/>
</wsdl:input>
<wsdlutput name="helloWorldResponse">
<wsdlsoap:body namespace="http://
helloworld.services.jjs.xxxxxxxxx.com" use="literal"/>
</wsdlutput>
</wsdlperation>
</wsdl:binding>
<wsdl:service name="HelloWorld8Service">
<wsdlort binding="impl:HelloWorld8SoapBinding"
name="HelloWorld8">
<wsdlsoap:address location="http://localhost:9084/
jlp_jjs_Services/services/HelloWorld8"/>
</wsdlort>
</wsdl:service>
</wsdl:definitions>
Heres the service....
public class HelloWorld8 {
public String helloWorld(HelloWorld8Msg aMsg) {
int arraySize = aMsg.getMyArray().length;
System.out.println("arraySize=[" + arraySize + "]");
String arrayContent = "";
for (int n = 0; n < arraySize; n++) {
arrayContent = arrayContent + ", " + aMsg.getMyArray()[n];
System.out.println("arrayContent=[" + arrayContent + "]");
}
return "Hello " + aMsg.getName() + "." + arrayContent + ".";
}
}
Heres the message...
public class HelloWorld8Msg extends AbstractHelloWorld8Msg {
public String name = "aa";
public HelloWorld8Msg() {
name = "bb";
}
public HelloWorld8Msg(String anName, HelloItem[] anMyArray) {
name = anName;
setMyArray(anMyArray);
}
/**
* @return Returns the name.
*/
public String getName() {
return name;
}
/**
* @param anName The name to set.
*/
public void setName(String anName) {
name = anName;
}
}
Heres HelloItem...
public class HelloItem implements Serializable {
public String key;
public String value;
public HelloItem(String anKey, String anValue) {
key = anKey;
value = anValue;
}
public String getKey() {
return key;
}
public void setKey(String anKey) {
key = anKey;
}
public String getValue() {
return value;
}
public void setValue(String anValue) {
value = anValue;
}
public String toString() {
return "key=[" + key + "], value=[" + value + "]";
}
}
Heres the super class...
import java.io.Serializable;
public class AbstractHelloWorld8Msg implements Serializable {
public HelloItem[] myArray = {new HelloItem("aaa", "Fred"), new
HelloItem("bbb", "Wilma"), new HelloItem("ccc", "Pebbles")};
/**
* @return Returns the myArray.
*/
public HelloItem getMyArray(int i) {
return myArray;
}
public HelloItem[] getMyArray() {
return myArray;
}
/**
* @param anMyArray The myArray to set.
*/
public void setMyArray(HelloItem[] anMyArray) {
myArray = anMyArray;
}
public void setMyArray(int i, HelloItem aHelloItem) {
myArray = aHelloItem;
}
}
I can get webservices to work ok when the message is a wrapper
containing Strings, ints, and arrays of Strings or ints, but as soon
as I try to use an array of complex types it fails.
The way it fails is that it says the array is an array of
'xsd:anyType' whereas I would expect something like 'impl:mytype'
where mytype would then have 'complexType' entry which would explain
that its just a String and an Int (for example)
Can anyone tell me how I should structure a message object to contain
arrays of wrapper classes? - or any neat tricks to avoid needing
arrays of wrapper classes.
Many Thanks
David Bevan
http://www.davidbevan.co.uk
Heres some wsdl....
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://
helloworld.services.jjs.xxxxxxxxx.com" xmlns:impl="http://
helloworld.services.jjs.xxxxxxxxx.com" xmlns:intf="http://
helloworld.services.jjs.xxxxxxxxx.com" xmlns:wsdl="http://
schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/
wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<wsdl:types>
<schema targetNamespace="http://
helloworld.services.jjs.xxxxxxxxx.com" xmlns="http://www.w3.org/2001/
XMLSchema" xmlns:impl="http://helloworld.services.jjs.xxxxxxxxx.com"
xmlns:intf="http://helloworld.services.jjs.xxxxxxxxx.com"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://
www.w3.org/2001/XMLSchema">
<complexType name="HelloWorld8Msg">
<complexContent>
<extension base="impl:AbstractHelloWorld8Msg">
<sequence>
<element name="name" nillable="true" type="xsd:string"/>
</sequence>
</extension>
</complexContent>
</complexType>
<complexType name="AbstractHelloWorld8Msg">
<sequence>
<element maxOccurs="unbounded" name="myArray" nillable="true"
type="xsd:string"/>
</sequence>
</complexType>
<element name="HelloWorld8Msg" nillable="true"
type="impl:HelloWorld8Msg"/>
<complexType name="HelloWorld8OutMsg">
<complexContent>
<extension base="impl:AbstractHelloWorld8OutMsg">
<sequence>
<element name="name" nillable="true" type="xsd:string"/>
</sequence>
</extension>
</complexContent>
</complexType>
<complexType name="AbstractHelloWorld8OutMsg">
<sequence>
<element maxOccurs="unbounded" name="myArray" nillable="true"
type="xsd:anyType"/>
</sequence>
</complexType>
<element name="HelloWorld8OutMsg" nillable="true"
type="impl:HelloWorld8OutMsg"/>
</schema>
</wsdl:types>
<wsdl:message name="helloWorldResponse">
<wsdlart name="helloWorldReturn" type="impl:HelloWorld8OutMsg"/
</wsdl:message>
<wsdl:message name="helloWorldRequest">
<wsdlart name="aMsg" type="impl:HelloWorld8Msg"/>
</wsdl:message>
<wsdlortType name="HelloWorld8">
<wsdlperation name="helloWorld" parameterOrder="aMsg">
<wsdl:input message="impl:helloWorldRequest"
name="helloWorldRequest"/>
<wsdlutput message="impl:helloWorldResponse"
name="helloWorldResponse"/>
</wsdlperation>
</wsdlortType>
<wsdl:binding name="HelloWorld8SoapBinding"
type="impl:HelloWorld8">
<wsdlsoap:binding style="rpc" transport="http://
schemas.xmlsoap.org/soap/http"/>
<wsdlperation name="helloWorld">
<wsdlsoapperation soapAction=""/>
<wsdl:input name="helloWorldRequest">
<wsdlsoap:body namespace="http://
helloworld.services.jjs.xxxxxxxxx.com" use="literal"/>
</wsdl:input>
<wsdlutput name="helloWorldResponse">
<wsdlsoap:body namespace="http://
helloworld.services.jjs.xxxxxxxxx.com" use="literal"/>
</wsdlutput>
</wsdlperation>
</wsdl:binding>
<wsdl:service name="HelloWorld8Service">
<wsdlort binding="impl:HelloWorld8SoapBinding"
name="HelloWorld8">
<wsdlsoap:address location="http://localhost:9084/
jlp_jjs_Services/services/HelloWorld8"/>
</wsdlort>
</wsdl:service>
</wsdl:definitions>
Heres the service....
public class HelloWorld8 {
public String helloWorld(HelloWorld8Msg aMsg) {
int arraySize = aMsg.getMyArray().length;
System.out.println("arraySize=[" + arraySize + "]");
String arrayContent = "";
for (int n = 0; n < arraySize; n++) {
arrayContent = arrayContent + ", " + aMsg.getMyArray()[n];
System.out.println("arrayContent=[" + arrayContent + "]");
}
return "Hello " + aMsg.getName() + "." + arrayContent + ".";
}
}
Heres the message...
public class HelloWorld8Msg extends AbstractHelloWorld8Msg {
public String name = "aa";
public HelloWorld8Msg() {
name = "bb";
}
public HelloWorld8Msg(String anName, HelloItem[] anMyArray) {
name = anName;
setMyArray(anMyArray);
}
/**
* @return Returns the name.
*/
public String getName() {
return name;
}
/**
* @param anName The name to set.
*/
public void setName(String anName) {
name = anName;
}
}
Heres HelloItem...
public class HelloItem implements Serializable {
public String key;
public String value;
public HelloItem(String anKey, String anValue) {
key = anKey;
value = anValue;
}
public String getKey() {
return key;
}
public void setKey(String anKey) {
key = anKey;
}
public String getValue() {
return value;
}
public void setValue(String anValue) {
value = anValue;
}
public String toString() {
return "key=[" + key + "], value=[" + value + "]";
}
}
Heres the super class...
import java.io.Serializable;
public class AbstractHelloWorld8Msg implements Serializable {
public HelloItem[] myArray = {new HelloItem("aaa", "Fred"), new
HelloItem("bbb", "Wilma"), new HelloItem("ccc", "Pebbles")};
/**
* @return Returns the myArray.
*/
public HelloItem getMyArray(int i) {
return myArray;
}
public HelloItem[] getMyArray() {
return myArray;
}
/**
* @param anMyArray The myArray to set.
*/
public void setMyArray(HelloItem[] anMyArray) {
myArray = anMyArray;
}
public void setMyArray(int i, HelloItem aHelloItem) {
myArray = aHelloItem;
}
}