Reputation: 5848
Little different from my previous question. I want to keep these as 2 individual questions (as the other one was answered).
I have a web service which I want to pass back a Vector<Vector<Object>>
or ArrayList<ArrayList<Object>>
to the client. For this I have created a simple POJO class (thanks Abhisek Bose) for this called VectorWS
. The implementation using the Vector
is as follows:
public class VectorWS {
private Vector vector;
public VectorWS() {
}
public VectorWS(Vector v) {
vector = v;
}
public Vector getVector() {
return vector;
}
public void setVector(Vector vector) {
this.vector = vector;
}
}
The interface implementation is as follows:
@WebService
@SOAPBinding(style = Style.RPC)
public interface ISQLServerConnectionWS {
@WebMethod
VectorWS executeSelectSQL(@WebParam(name = "sqlStatements") String sqlStatements);
}
The server implementation is as follows:
@WebService(endpointInterface="WebServices.ISQLServerConnectionWS")
public class SQLConnectionWSServer
implements ISQLServerConnectionWS {
@Override
public VectorWS executeSelectSQL(String sqlStatements) {
System.out.println("You are calling executeSelectSQL with " + sqlStatements );
Vector results = new Vector();
Vector row1 = new Vector();
Vector row2 = new Vector();
row1.add( "Name" );
row2.add( "Asamoah" );
results.add( row1 );
results.add( row2 );
VectorWS vws = new VectorWS(new ArrayList(results));
return vws;
}
}
Client calls the server service method as:
VectorWS results = server.executeSelectSQL( sqlStatements );
However, the server throws an exception when the vws
is returned. I have tried this for both Vector
and ArrayList
.
The exception (from the ArrayList) in this instance can be found at the end of the post.
My question is if we cannot return ArrayList<ArrayList<Object>>
what would one recommend?
Only thing that comes to mind would be ArrayList<Object[]>
. Any ideas?
Many thanks,
Andez
Here is the exception stack trace:
javax.xml.ws.WebServiceException: javax.xml.bind.MarshalException
- with linked exception:
[javax.xml.bind.JAXBException: class java.util.ArrayList nor any of its super class is known to this context.]
at com.sun.xml.internal.ws.message.jaxb.JAXBMessage.writePayloadTo(JAXBMessage.java:318)
at com.sun.xml.internal.ws.message.AbstractMessageImpl.writeTo(AbstractMessageImpl.java:131)
at com.sun.xml.internal.ws.encoding.StreamSOAPCodec.encode(StreamSOAPCodec.java:98)
at com.sun.xml.internal.ws.encoding.SOAPBindingCodec.encode(SOAPBindingCodec.java:249)
at com.sun.xml.internal.ws.transport.http.HttpAdapter.encodePacket(HttpAdapter.java:328)
at com.sun.xml.internal.ws.transport.http.HttpAdapter.access$100(HttpAdapter.java:82)
at com.sun.xml.internal.ws.transport.http.HttpAdapter$HttpToolkit.handle(HttpAdapter.java:470)
at com.sun.xml.internal.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:233)
at com.sun.xml.internal.ws.transport.http.server.WSHttpHandler.handleExchange(WSHttpHandler.java:95)
at com.sun.xml.internal.ws.transport.http.server.WSHttpHandler.handle(WSHttpHandler.java:80)
at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:65)
at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:65)
at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:68)
at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:555)
at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:65)
at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:527)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
Caused by: javax.xml.bind.MarshalException
- with linked exception:
[javax.xml.bind.JAXBException: class java.util.ArrayList nor any of its super class is known to this context.]
at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:268)
at com.sun.xml.internal.bind.v2.runtime.BridgeImpl.marshal(BridgeImpl.java:89)
at com.sun.xml.internal.bind.api.Bridge.marshal(Bridge.java:130)
at com.sun.xml.internal.ws.message.jaxb.JAXBMessage.writePayloadTo(JAXBMessage.java:310)
... 18 more
Caused by: javax.xml.bind.JAXBException: class java.util.ArrayList nor any of its super class is known to this context.
at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:234)
at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:249)
at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:641)
at com.sun.xml.internal.bind.v2.runtime.property.ArrayElementNodeProperty.serializeItem(ArrayElementNodeProperty.java:54)
at com.sun.xml.internal.bind.v2.runtime.property.ArrayElementProperty.serializeListBody(ArrayElementProperty.java:157)
at com.sun.xml.internal.bind.v2.runtime.property.ArrayERProperty.serializeBody(ArrayERProperty.java:141)
at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:321)
at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:687)
at com.sun.xml.internal.bind.v2.runtime.BridgeImpl.marshal(BridgeImpl.java:136)
at com.sun.xml.internal.bind.v2.runtime.CompositeStructureBeanInfo.serializeBody(CompositeStructureBeanInfo.java:96)
at com.sun.xml.internal.bind.v2.runtime.CompositeStructureBeanInfo.serializeBody(CompositeStructureBeanInfo.java:44)
at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:687)
at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:263)
... 21 more
Caused by: javax.xml.bind.JAXBException: class java.util.ArrayList nor any of its super class is known to this context.
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getBeanInfo(JAXBContextImpl.java:554)
at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:636)
... 31 more
Upvotes: 0
Views: 1970
Reputation: 5848
In a nutshell, following on from user756212's answer, the VectorWS can be serialized/deserialized with:
public String serialize(Object o) {
String s;
ByteArrayOutputStream stream = new ByteArrayOutputStream();
XMLEncoder encoder = new XMLEncoder( new BufferedOutputStream( stream ) );
encoder.writeObject(o);
encoder.close();
s = stream.toString();
return s;
}
private Object deserialize(String s) {
XMLDecoder decoder = new XMLDecoder( new ByteArrayInputStream( s.getBytes() ) );
return decoder.readObject();
}
And called with:
VectorWS vws = (VectorWS) deserialize( results );
Upvotes: 0
Reputation: 522
Have you tried Serializing the object, then running Base64 on the serialization, returning that over the wire, and then decoding the base64 and deserializing upon receipt?
Basically your method now would return a string, that is the Base64 encoded serialization of the List/Vectors, and the receiver would need to unencode the string and decode the object.
I have used this sort of technique to serialize and deserialize complex list and vector objects.
Upvotes: 1