Andez
Andez

Reputation: 5848

Java Web Services and returning Vector<Vector<Object>>

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

Answers (2)

Andez
Andez

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

user756212
user756212

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

Related Questions