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