The problem is not so much the mapping of vector.  At least, it is possible to map it to soap and back to java.  Also there is a mapping to/from c#.  It uses object [] to map to this.  I've attached some sample files.  The original service is in CustomerServicex.java.  I've cleaned this up from some real code I have so don't worry if there are minor compile errors or the class name doesn't match the file name.  The CustomerService class defines my web service.  One of the methods is getContactsByMemberID.  This method returns a Vector.  Presumably this will be filled with references to Contact objects.  Works great in java/rmi/ejb land.  Problem is that although a reasonable mapping happens to soap via a complex type called Vector that is unbounded and supports xsd:anyType, and although this maps reasonably to a c# type of object [], the problem happens at run time.   If I pass data through this that can't be serialized I get an exception.  Can't be predicted at compile time because Vector is a collection of 'untyped' objects.  OK, I know that Object is a type, but that's not the point.  You don't know if it's a Contact object that can be serialized or if it is some FooBar object that cannot be.  Plus, the wsdl doesn't know for sure what it is going across, so it can't for sure have described the complex type.
 
I've used C# as the sample client because I figure it's a reasonable test - service in java, client in c#.  I've decided to always create service interfaces that have completely typed collections.  This means mapping a vector to a typed array.  Shouldn't be a problem.  The service interface can still be non-specific relative to the number of elements of the array.  Plus, you aren't going to try to hand someone a reference to a collection for them to add to it anyway, so the point of a dynamic collection is lost anyway.  Only problem is if you really do have a collection of heterogeneous object types.  If so, you probably want to figure out a different service interface anyway.
 
Hope this helps.  Also hope that the attachments come through on the list.  I'm more of a lurker, so contributing to lists is new to me.
 
tc
 
 
----- Original Message -----
Sent: Friday, November 22, 2002 12:35 PM
Subject: Vectors in JavaBeans


My web service returns a JavaBean with a vector of another type of bean as a member. In other words I have a "FamilyBean" that contains a Vector of "MemberBeans".  With a Java web client this is not a problem, because the client "understands" what a Vector is. But I want to support all types of clients transparently.

Is my only option to alter my JavaBean to use an array instead of a Vector?

It is possible using type mapping to represent a Vector of objects as an array? (Without having to alter the beans?)

Is there some other solution to this problem?

 

Attachment: Contact.java
Description: Binary data

Attachment: CustomerServicex.java
Description: Binary data

//------------------------------------------------------------------------------
// <autogenerated>
//     This code was generated by a tool.
//     Runtime Version: 1.0.3705.288
//
//     Changes to this file may cause incorrect behavior and will be lost if 
//     the code is regenerated.
// </autogenerated>
//------------------------------------------------------------------------------

// 
// This source code was auto-generated by wsdl, Version=1.0.3705.288.
// 
using System.Diagnostics;
using System.Xml.Serialization;
using System;
using System.Web.Services.Protocols;
using System.ComponentModel;
using System.Web.Services;


/// <remarks/>
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Web.Services.WebServiceBindingAttribute(Name="customerserviceSoapBinding", 
Namespace="http://customerService.x.com";)]
public class CustomerServiceService : 
System.Web.Services.Protocols.SoapHttpClientProtocol {
    
    /// <remarks/>
    public CustomerServiceService() {
        this.Url = "http://localhost:8080/axis/services/customerservice";;
    }
    
    /// <remarks/>
    [System.Web.Services.Protocols.SoapRpcMethodAttribute("", 
RequestNamespace="http://customerService.x.com";, 
ResponseNamespace="http://customerService.x.com";)]
    public void addContact(Contact in0, Action in1, ID in2) {
        this.Invoke("addContact", new object[] {
                    in0,
                    in1,
                    in2});
    }
    
    /// <remarks/>
    public System.IAsyncResult BeginaddContact(Contact in0, Action in1, ID in2, 
System.AsyncCallback callback, object asyncState) {
        return this.BeginInvoke("addContact", new object[] {
                    in0,
                    in1,
                    in2}, callback, asyncState);
    }
    
    /// <remarks/>
    public void EndaddContact(System.IAsyncResult asyncResult) {
        this.EndInvoke(asyncResult);
    }
    
    /// <remarks/>
    [System.Web.Services.Protocols.SoapRpcMethodAttribute("", 
RequestNamespace="http://customerService.x.com";, 
ResponseNamespace="http://customerService.x.com";)]
    public void updateContact(Contact in0) {
        this.Invoke("updateContact", new object[] {
                    in0});
    }
    
    /// <remarks/>
    public System.IAsyncResult BeginupdateContact(Contact in0, System.AsyncCallback 
callback, object asyncState) {
        return this.BeginInvoke("updateContact", new object[] {
                    in0}, callback, asyncState);
    }
    
    /// <remarks/>
    public void EndupdateContact(System.IAsyncResult asyncResult) {
        this.EndInvoke(asyncResult);
    }
    
    /// <remarks/>
    [System.Web.Services.Protocols.SoapRpcMethodAttribute("", 
RequestNamespace="http://customerService.x.com";, 
ResponseNamespace="http://customerService.x.com";)]
    [return: 
System.Xml.Serialization.SoapElementAttribute("getContactsByMemberIDReturn")]
    public Vector getContactsByMemberID(ID in0) {
        object[] results = this.Invoke("getContactsByMemberID", new object[] {
                    in0});
        return ((Vector)(results[0]));
    }
    
    /// <remarks/>
    public System.IAsyncResult BegingetContactsByMemberID(ID in0, System.AsyncCallback 
callback, object asyncState) {
        return this.BeginInvoke("getContactsByMemberID", new object[] {
                    in0}, callback, asyncState);
    }
    
    /// <remarks/>
    public Vector EndgetContactsByMemberID(System.IAsyncResult asyncResult) {
        object[] results = this.EndInvoke(asyncResult);
        return ((Vector)(results[0]));
    }
}

/// <remarks/>
[System.Xml.Serialization.SoapTypeAttribute("Contact", "http://bom.x.com";)]
public class Contact {
    
    /// <remarks/>
    public int contactID;
    
    /// <remarks/>
    public string contactName;
    
    /// <remarks/>
    public string contactPhone;
}

/// <remarks/>
[System.Xml.Serialization.SoapTypeAttribute("Vector", 
"http://xml.apache.org/xml-soap";)]
public class Vector {
    
    /// <remarks/>
    public object[] item;
}

/// <remarks/>
[System.Xml.Serialization.SoapTypeAttribute("ID", "http://bom.x.com";)]
public class ID {
    
    /// <remarks/>
    [System.Xml.Serialization.SoapElementAttribute("ID")]
    public int ID1;
}

/// <remarks/>
[System.Xml.Serialization.SoapTypeAttribute("Action", "http://bom.x.com";)]
public class Action {
}

Attachment: CustomerService.wsdl
Description: Binary data

Reply via email to