You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-user@axis.apache.org by Ma...@micorp.com on 2004/06/15 19:13:34 UTC

Array Deserialized Incorrectly

Hi,

I used java2wsdl when publishing an axis service.  The service method 
expects a parameter class with contains an array of a different 
(non-primitive) class.  The client has no problem calling the service, and 
the service does almost everything perfectly.  However, no matter how many 
array elements I send to the service, it only receives an array of length 
= 1 for processing.

Here is the wsdl:

  <?xml version="1.0" encoding="UTF-8" ?> 
<wsdl:definitions targetNamespace="com.MY_COMPANY.axis.metrics" 
xmlns="http://schemas.xmlsoap.org/wsdl/" 
xmlns:apachesoap="http://xml.apache.org/xml-soap" 
xmlns:impl="com.MY_COMPANY.axis.metrics" 
xmlns:intf="com.MY_COMPANY.axis.metrics" 
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
xmlns:tns1="http://metrics.MY_COMPANY.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://metrics.MY_COMPANY.com" 
xmlns="http://www.w3.org/2001/XMLSchema">
<complexType name="Metric">
<sequence>
  <element name="begin" type="xsd:long" /> 
  <element name="dateTime" type="xsd:long" /> 
  <element name="end" type="xsd:long" /> 
  <element name="level" type="xsd:int" /> 
  <element name="metricCreator" nillable="true" type="xsd:string" /> 
  <element name="metricName" nillable="true" type="xsd:string" /> 
  <element name="type" type="xsd:int" /> 
  </sequence>
  </complexType>
<complexType name="MetricComposite">
<sequence>
  <element name="metricLevel" type="xsd:int" /> 
  <element name="metricSponsor" nillable="true" type="xsd:string" /> 
  <element name="metricsArray" nillable="true" 
type="impl:ArrayOf_tns1_Metric" /> 
  </sequence>
  </complexType>
  </schema>
<schema targetNamespace="com.MY_COMPANY.axis.metrics" 
xmlns="http://www.w3.org/2001/XMLSchema">
<complexType name="ArrayOf_tns1_Metric">
<complexContent>
<restriction base="soapenc:Array">
  <attribute ref="soapenc:arrayType" wsdl:arrayType="tns1:Metric[]" /> 
  </restriction>
  </complexContent>
  </complexType>
<element name="processMetricComposite">
<complexType>
<sequence>
  <element name="in0" type="tns1:MetricComposite" /> 
  </sequence>
  </complexType>
  </element>
<element name="processMetricCompositeResponse">
<complexType>
<sequence>
  <element name="processMetricCompositeReturn" type="xsd:boolean" /> 
  </sequence>
  </complexType>
  </element>
  </schema>
  </wsdl:types>
<wsdl:message name="processMetricCompositeResponse">
  <wsdl:part element="impl:processMetricCompositeResponse" 
name="parameters" /> 
  </wsdl:message>
<wsdl:message name="processMetricCompositeRequest">
  <wsdl:part element="impl:processMetricComposite" name="parameters" /> 
  </wsdl:message>
<wsdl:portType name="MetricsServiceIF">
<wsdl:operation name="processMetricComposite" parameterOrder="">
  <wsdl:input message="impl:processMetricCompositeRequest" 
name="processMetricCompositeRequest" /> 
  <wsdl:output message="impl:processMetricCompositeResponse" 
name="processMetricCompositeResponse" /> 
  </wsdl:operation>
  </wsdl:portType>
<wsdl:binding name="MetricsServiceSoapBinding" 
type="impl:MetricsServiceIF">
  <wsdlsoap:binding style="document" 
transport="http://schemas.xmlsoap.org/soap/http" /> 
<wsdl:operation name="processMetricComposite">
  <wsdlsoap:operation soapAction="" /> 
<wsdl:input name="processMetricCompositeRequest">
  <wsdlsoap:body namespace="com.MY_COMPANY.axis.metrics" use="literal" /> 
  </wsdl:input>
<wsdl:output name="processMetricCompositeResponse">
  <wsdlsoap:body namespace="com.MY_COMPANY.axis.metrics" use="literal" /> 
  </wsdl:output>
  </wsdl:operation>
  </wsdl:binding>
<wsdl:service name="MetricsServiceIFService">
<wsdl:port binding="impl:MetricsServiceSoapBinding" name="MetricsService">
  <wsdlsoap:address 
location="http://OUR_HOST/axis/services/MetricsService" /> 
  </wsdl:port>
  </wsdl:service>
  </wsdl:definitions>

When the client inserts 3 metrics, here is the outgoing SOAP request XML 
as picked up by the Handler:

<?xml version="1.0" encoding="UTF-8"?>
<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>
  <processMetricComposite xmlns="com.micorp.axis.metrics">
   <in0 xmlns="">
    <metricLevel>1</metricLevel>
    <metricSponsor>Test Sponsor</metricSponsor>
    <metricsArray xmlns:ns1="http://metrics.micorp.com">
     <begin>1087307889439</begin>
     <dateTime>1087317889439</dateTime>
     <end>1087308889439</end>
     <level>0</level>
     <metricCreator>testSendMetric_1</metricCreator>
     <metricName>my metric_1</metricName>
     <type>1</type>
    </metricsArray>
    <metricsArray>
     <begin>1087312889439</begin>
     <dateTime>1087317889439</dateTime>
     <end>1087313889439</end>
     <level>0</level>
     <metricCreator>testSendMetric_2</metricCreator>
     <metricName>my metric_2</metricName>
     <type>1</type>
    </metricsArray>
    <metricsArray>
     <begin>1087312889439</begin>
     <dateTime>1087317889439</dateTime>
     <end>1087313889439</end>
     <level>0</level>
     <metricCreator>testSendMetric_3</metricCreator>
     <metricName>my metric_3</metricName>
     <type>1</type>
    </metricsArray>
   </in0>
  </processMetricComposite>
 </soapenv:Body>
</soapenv:Envelope>

Again, during processing, the service implementation only gets an array 
(of Metric) of length = 1.  The message completes, albeit with what 
appears to be partial input, and flawlessly returns a positive response to 
the client.

Am I doing something wrong here javs2wsdl?  The only place that I am a 
little concerned about is the axis-generated MetricComposite definition. I 
can include additional bits upon request.  The typeDesc is initialized in 
the following manner:

public class MetricComposite  implements java.io.Serializable {
    private int metricLevel;
    private java.lang.String metricSponsor;
    private com.micorp.metrics.Metric[] metricsArray;

    public MetricComposite() {
    }
.
.
.

    public com.micorp.metrics.Metric[] getMetricsArray() {
        return metricsArray;
    }

    public void setMetricsArray(com.micorp.metrics.Metric[] metricsArray) {
        this.metricsArray = metricsArray;
    }

.
.
.

    // Type metadata
    private static org.apache.axis.description.TypeDesc typeDesc =
        new org.apache.axis.description.TypeDesc(MetricComposite.class);

    static {
        typeDesc.setXmlType(new javax.xml.namespace.QName("http://metrics.MY_COMPANY.com", "MetricComposite"));
        org.apache.axis.description.ElementDesc elemField = new org.apache.axis.description.ElementDesc();
        elemField.setFieldName("metricLevel");
        elemField.setXmlName(new javax.xml.namespace.QName("", "metricLevel"));
        elemField.setXmlType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "int"));
        typeDesc.addFieldDesc(elemField);
        elemField = new org.apache.axis.description.ElementDesc();
        elemField.setFieldName("metricSponsor");
        elemField.setXmlName(new javax.xml.namespace.QName("", "metricSponsor"));
        elemField.setXmlType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"));
        typeDesc.addFieldDesc(elemField);
        elemField = new org.apache.axis.description.ElementDesc();
        elemField.setFieldName("metricsArray");
        elemField.setXmlName(new javax.xml.namespace.QName("", "metricsArray"));
        elemField.setXmlType(new javax.xml.namespace.QName("http://metrics.MY_COMPANY.com", "Metric"));
        typeDesc.addFieldDesc(elemField);
    }

I thought the metricsArray definition would have possibly suggested an 
array of Metric (i.e., Metric[]) rather than simply Metric, but I may not 
be comfortable enough at this point with the code.

Thanks, in advance, for taking a look at the source.

Regards,
Matt Hanson

RE: Array Deserialized Incorrectly

Posted by Anne Thomas Manes <an...@manes.net>.
 Well for starters, you shouldn't use soapenc:Array  with document/literal
services.
I notice that your SOAP message isn't generated properly. It should contain
an element called <metricsArray>, which should contain a set of three
<metric> elements, except that instead you get three <metricsArray>
elements. The service sees only the one array element in the first array and
ignores the following two (unexpected) elements. I suspect it's because
you've defined the array using soapenc:Array.
 
What version of Axis are you using? I suggest you use the latest Axis 1.2
build.
 
Anne
 
  _____  

From: Matthew.Hanson@micorp.com [mailto:Matthew.Hanson@micorp.com] 
Sent: Tuesday, June 15, 2004 1:14 PM
To: axis-user@ws.apache.org
Subject: Array Deserialized Incorrectly
 

Hi, 

I used java2wsdl when publishing an axis service.  The service method
expects a parameter class with contains an array of a different
(non-primitive) class.  The client has no problem calling the service, and
the service does almost everything perfectly.  However, no matter how many
array elements I send to the service, it only receives an array of length =
1 for processing. 

Here is the wsdl: 

  <?xml version="1.0" encoding="UTF-8" ?> 
<wsdl:definitions targetNamespace="com.MY_COMPANY.axis.metrics"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:apachesoap="http://xml.apache.org/xml-soap"
xmlns:impl="com.MY_COMPANY.axis.metrics"
xmlns:intf="com.MY_COMPANY.axis.metrics"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns1="http://metrics.MY_COMPANY.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://metrics.MY_COMPANY.com"
xmlns="http://www.w3.org/2001/XMLSchema"> 
<complexType name="Metric"> 
<sequence> 
  <element name="begin" type="xsd:long" /> 
  <element name="dateTime" type="xsd:long" /> 
  <element name="end" type="xsd:long" /> 
  <element name="level" type="xsd:int" /> 
  <element name="metricCreator" nillable="true" type="xsd:string" /> 
  <element name="metricName" nillable="true" type="xsd:string" /> 
  <element name="type" type="xsd:int" /> 
  </sequence> 
  </complexType> 
<complexType name="MetricComposite"> 
<sequence> 
  <element name="metricLevel" type="xsd:int" /> 
  <element name="metricSponsor" nillable="true" type="xsd:string" /> 
  <element name="metricsArray" nillable="true"
type="impl:ArrayOf_tns1_Metric" /> 
  </sequence> 
  </complexType> 
  </schema> 
<schema targetNamespace="com.MY_COMPANY.axis.metrics"
xmlns="http://www.w3.org/2001/XMLSchema"> 
<complexType name="ArrayOf_tns1_Metric"> 
<complexContent> 
<restriction base="soapenc:Array"> 
  <attribute ref="soapenc:arrayType" wsdl:arrayType="tns1:Metric[]" /> 
  </restriction> 
  </complexContent> 
  </complexType> 
<element name="processMetricComposite"> 
<complexType> 
<sequence> 
  <element name="in0" type="tns1:MetricComposite" /> 
  </sequence> 
  </complexType> 
  </element> 
<element name="processMetricCompositeResponse"> 
<complexType> 
<sequence> 
  <element name="processMetricCompositeReturn" type="xsd:boolean" /> 
  </sequence> 
  </complexType> 
  </element> 
  </schema> 
  </wsdl:types> 
<wsdl:message name="processMetricCompositeResponse"> 
  <wsdl:part element="impl:processMetricCompositeResponse" name="parameters"
/> 
  </wsdl:message> 
<wsdl:message name="processMetricCompositeRequest"> 
  <wsdl:part element="impl:processMetricComposite" name="parameters" /> 
  </wsdl:message> 
<wsdl:portType name="MetricsServiceIF"> 
<wsdl:operation name="processMetricComposite" parameterOrder=""> 
  <wsdl:input message="impl:processMetricCompositeRequest"
name="processMetricCompositeRequest" /> 
  <wsdl:output message="impl:processMetricCompositeResponse"
name="processMetricCompositeResponse" /> 
  </wsdl:operation> 
  </wsdl:portType> 
<wsdl:binding name="MetricsServiceSoapBinding" type="impl:MetricsServiceIF">

  <wsdlsoap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" /> 
<wsdl:operation name="processMetricComposite"> 
  <wsdlsoap:operation soapAction="" /> 
<wsdl:input name="processMetricCompositeRequest"> 
  <wsdlsoap:body namespace="com.MY_COMPANY.axis.metrics" use="literal" /> 
  </wsdl:input> 
<wsdl:output name="processMetricCompositeResponse"> 
  <wsdlsoap:body namespace="com.MY_COMPANY.axis.metrics" use="literal" /> 
  </wsdl:output> 
  </wsdl:operation> 
  </wsdl:binding> 
<wsdl:service name="MetricsServiceIFService"> 
<wsdl:port binding="impl:MetricsServiceSoapBinding" name="MetricsService"> 
  <wsdlsoap:address location="http://OUR_HOST/axis/services/MetricsService"
/> 
  </wsdl:port> 
  </wsdl:service> 
  </wsdl:definitions> 

When the client inserts 3 metrics, here is the outgoing SOAP request XML as
picked up by the Handler: 

<?xml version="1.0" encoding="UTF-8"?> 
<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> 
  <processMetricComposite xmlns="com.micorp.axis.metrics"> 
   <in0 xmlns=""> 
    <metricLevel>1</metricLevel> 
    <metricSponsor>Test Sponsor</metricSponsor> 
    <metricsArray xmlns:ns1="http://metrics.micorp.com"> 
     <begin>1087307889439</begin> 
     <dateTime>1087317889439</dateTime> 
     <end>1087308889439</end> 
     <level>0</level> 
     <metricCreator>testSendMetric_1</metricCreator> 
     <metricName>my metric_1</metricName> 
     <type>1</type> 
    </metricsArray> 
    <metricsArray> 
     <begin>1087312889439</begin> 
     <dateTime>1087317889439</dateTime> 
     <end>1087313889439</end> 
     <level>0</level> 
     <metricCreator>testSendMetric_2</metricCreator> 
     <metricName>my metric_2</metricName> 
     <type>1</type> 
    </metricsArray> 
    <metricsArray> 
     <begin>1087312889439</begin> 
     <dateTime>1087317889439</dateTime> 
     <end>1087313889439</end> 
     <level>0</level> 
     <metricCreator>testSendMetric_3</metricCreator> 
     <metricName>my metric_3</metricName> 
     <type>1</type> 
    </metricsArray> 
   </in0> 
  </processMetricComposite> 
 </soapenv:Body> 
</soapenv:Envelope> 

Again, during processing, the service implementation only gets an array (of
Metric) of length = 1.  The message completes, albeit with what appears to
be partial input, and flawlessly returns a positive response to the client. 

Am I doing something wrong here javs2wsdl?  The only place that I am a
little concerned about is the axis-generated MetricComposite definition.  I
can include additional bits upon request.  The typeDesc is initialized in
the following manner: 

public class MetricComposite  implements java.io.Serializable { 
    private int metricLevel; 
    private java.lang.String metricSponsor; 
    private com.micorp.metrics.Metric[] metricsArray; 

    public MetricComposite() { 
    } 
. 
. 
. 

    public com.micorp.metrics.Metric[] getMetricsArray() { 
        return metricsArray; 
    } 

    public void setMetricsArray(com.micorp.metrics.Metric[] metricsArray) { 
        this.metricsArray = metricsArray; 
    } 

. 
. 
. 

    // Type metadata 
    private static org.apache.axis.description.TypeDesc typeDesc = 
        new org.apache.axis.description.TypeDesc(MetricComposite.class); 

    static { 
        typeDesc.setXmlType(new
javax.xml.namespace.QName("http://metrics.MY_COMPANY.com",
"MetricComposite")); 
        org.apache.axis.description.ElementDesc elemField = new
org.apache.axis.description.ElementDesc(); 
        elemField.setFieldName("metricLevel"); 
        elemField.setXmlName(new javax.xml.namespace.QName("",
"metricLevel")); 
        elemField.setXmlType(new
javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "int")); 
        typeDesc.addFieldDesc(elemField); 
        elemField = new org.apache.axis.description.ElementDesc(); 
        elemField.setFieldName("metricSponsor"); 
        elemField.setXmlName(new javax.xml.namespace.QName("",
"metricSponsor")); 
        elemField.setXmlType(new
javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string")); 
        typeDesc.addFieldDesc(elemField); 
        elemField = new org.apache.axis.description.ElementDesc(); 
        elemField.setFieldName("metricsArray"); 
        elemField.setXmlName(new javax.xml.namespace.QName("",
"metricsArray")); 
        elemField.setXmlType(new
javax.xml.namespace.QName("http://metrics.MY_COMPANY.com", "Metric")); 
        typeDesc.addFieldDesc(elemField); 
    } 

I thought the metricsArray definition would have possibly suggested an array
of Metric (i.e., Metric[]) rather than simply Metric, but I may not be
comfortable enough at this point with the code. 

Thanks, in advance, for taking a look at the source. 

Regards,
Matt Hanson