I recommend that you edit the generated WSDL:
1- remove the complexType definition for "ArrayOf_xsd_dateTime".
2- modify the complexType definition for "History" to:
<complexType name="History">
<sequence>
<element name="lastCalibration" nillable="true" type="xsd:dateTime"/>
<element name="nextCalibration" nillable="true" type="xsd:dateTime"/>
<element name="allCalibrations" nillable="true" type="xsd:dateTime" maxOccurs="unbounded"/>
...
</sequence>
</complexType>
I'm still not clear why your response message comes back unqualified.<sequence>
<element name="lastCalibration" nillable="true" type="xsd:dateTime"/>
<element name="nextCalibration" nillable="true" type="xsd:dateTime"/>
<element name="allCalibrations" nillable="true" type="xsd:dateTime" maxOccurs="unbounded"/>
...
</sequence>
</complexType>
Anne
On 6/7/06,
Artur Kraft <[EMAIL PROTECTED]> wrote:
Hello,
thanks for the answer. Now it gets clearer why only one date element was mapped to the Date[] array. So, the SOAP message send by axis is somehow not corresponding to the (also automatically created) WSDL.
> Perhaps you could provide a little more information (complete WSDL, WSDD,
> the methodology you used to implement the WSDL, WSDD, client, and server,
> etc). Also, what version of Axis are you using?
AppServer : Tomcat v5.5.17
Axis : Axis v1.4
Java : Java v1.5.0_06-b05
In the WSDL (automatically generated by axis) the declaration of my History class seems to be ok. I attached the whole WSDL file and show here the corresponding parts (which look fine to me, but not sure though):
Generated WSDL (cropped):
<?xml version="1.0" encoding="UTF-8"?><wsdl:definitions targetNamespace="http://mdmonitor.webservice.qsgrimm.de" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://mdmonitor.webservice.qsgrimm.de" xmlns:intf="http://mdmonitor.webservice.qsgrimm.de" xmlns:tns1="http://pub.mdmonitor.webservice.qsgrimm.de" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!--WSDL created by Apache Axis version: 1.4
Built on Apr 22, 2006 (06:55:48 PDT)-->
<wsdl:types>
<schema elementFormDefault="qualified" targetNamespace="http://mdmonitor.webservice.qsgrimm.de" xmlns="http://www.w3.org/2001/XMLSchema">
<import namespace="http://pub.mdmonitor.webservice.qsgrimm.de"/>
<element name="getHistory">
<complexType>
<sequence>
<element name="id" type="xsd:string"/>
</sequence>
</complexType>
</element>
<element name="getHistoryResponse">
<complexType>
<sequence>
<element name="getHistoryReturn" type="tns1:History"/>
</sequence>
</complexType>
</element>
<complexType name="ArrayOf_xsd_dateTime">
<sequence>
<element maxOccurs="unbounded" minOccurs="0" name="item" type="xsd:dateTime"/>
</sequence>
</complexType>
</schema>
<schema elementFormDefault="qualified" targetNamespace="http://pub.mdmonitor.webservice.qsgrimm.de" xmlns="http://www.w3.org/2001/XMLSchema">
<import namespace="http://mdmonitor.webservice.qsgrimm.de"/>
<complexType name="History">
<sequence>
<element name="lastCalibration" nillable="true" type="xsd:dateTime"/>
<element name="nextCalibration" nillable="true" type="xsd:dateTime"/>
<element name="allCalibrations" nillable="true" type="impl:ArrayOf_xsd_dateTime"/>
...
</sequence>
</complexType></schema>
</wsdl:types>
<wsdl:message name="getHistoryResponse">
<wsdl:part element="impl:getHistoryResponse" name="parameters"/>
</wsdl:message>
<wsdl:message name="getHistoryRequest">
<wsdl:part element="impl:getHistory" name="parameters"/>
</wsdl:message>
<wsdl:portType name="MeasuringDeviceMonitorIF">
<wsdl:operation name="getHistory">
<wsdl:input message="impl:getHistoryRequest" name="getHistoryRequest"/>
<wsdl:output message="impl:getHistoryResponse" name="getHistoryResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="mdmonitorSoapBinding" type="impl:MeasuringDeviceMonitorIF">
<wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getHistory">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="getHistoryRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getHistoryResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="MeasuringDeviceMonitorService">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Service mdmonitor</wsdl:documentation>
<wsdl:port binding="impl:mdmonitorSoapBinding" name="mdmonitor">
<wsdlsoap:address location="https://qsg.dyndns.org/axis/services/mdmonitor"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
The methodology I used to build my web service is the following:
Hopefully that points out the cause of the malfunctioning web service in the development process. Every suggestion is welcome. So, since most things are generated automatically, where should I start? Can I alter the way messages are send or should I try to alter the WSDL file to match the message. Which is the easier approach and which approach is the appropriate one?
- Create an java interface for the web service. The interface "MeasuringDeviceMonitorIF":
public interface MeasuringDeviceMonitorIF extends Remote {
public History getHistory(String id) throws RemoteException;
public Job[] getJobs() throws RemoteException;
public Job[] getJobsByDate(Date from, Date to) throws RemoteException;
public Job getJob(String jobId) throws RemoteException;
public Header[] getMeasuringDevices() throws RemoteException;
public Header[] getMeasuringDevicesByDate(Date from, Date to) throws RemoteException;
public Header getMeasuringDevice(String id) throws RemoteException;
public Measuring[] getMeasuringResults(String id) throws RemoteException;
public Measuring[] getMeasuringResultsUpdate(String id, Date lastKnownResult) throws RemoteException;
public Measuring getMeasuringResult(String id, Date date) throws RemoteException;
}- Using axis' Java2WSDL to create the wsdl file:
java -cp %AXIS_CLASSPATH% org.apache.axis.wsdl.Java2WSDL ^
--output mdmonitor.wsdl ^
--location https://qsg.dyndns.org/axis/services/mdmonitor ^
--implClass de.qsgrimm.webservice.mdmonitor.MeasuringDeviceMonitor ^
--typeMappingVersion 1.2 ^
--style WRAPPED ^
--use LITERAL ^
--extraClasses de.qsgrimm.webservice.mdmonitor.pub.History,(etc...) ^
de.qsgrimm.webservice.mdmonitor.MeasuringDeviceMonitorIF
- Using axis' WSDL2Java to create a deploy.wsdd:
java -cp %AXIS_CLASSPATH% -Djavax.net.ssl.trustStore=C:\Sun\_res\keycerts\client_keystore.key org.apache.axis.wsdl.WSDL2Java ^
--quiet ^
--server-side ^
--skeletonDeploy true ^
--output tmp ^
--all ^
--typeMappingVersion 1.2 ^
mdmonitor.wsdl
- Edit the deploy.wsdd:
- alter the service parameter value for "classname", "wsdlServiceElement", "extraClasses" to match my service
- remove all typemappings that use non-existent classes such as (because only class "History" exist):
qname="ns:>getHistoryResponse"
type="java:de.qsgrimm.webservice.mdmonitor.GetHistoryResponse"- Copy the compiled web service java classes to the dir "%AXIS_HOME%\WEB-INF\classes".
- Deploy the service using AdminClient and modified deploy.wsdd (attached "deploy.edited.wsdd")
- Generate the client classes:
java -cp %AXIS_CLASSPATH% -Djavax.net.ssl.trustStore=C:\Sun\_res\keycerts\client_keystore.key org.apache.axis.wsdl.WSDL2Java ^
--quiet ^
--server-side ^
--skeletonDeploy false ^
--package de.qsgrimm.wsclient.mdm ^
--output client-src ^
--testCase ^
--all ^
--typeMappingVersion 1.2 ^
mdmonitor.wsdl
- Invoke the client using https/SSL.
> Note also that your soap message is not valid because the
> "getHistoryResponse" element is unqualified.
I see....
"<soapenv:Body>
<getHistoryResponse xmlns="">
..."
But where can I set the elements to be qualified? As long as I can see it the WSDL already states it in the wsdl schema as:
elementFormDefault="qualified"
Propable it has to set in the wsdd, but what command is it in particular?
many thanks for your time and help!
kind regardsArtur
Anne Thomas Manes wrote:Artur,
The reason why the client gets only one "allCallibrations" element is that it is expecting "allCallibations" to be of type "impl:ArrayOf_xsd_dateType", not "xsd:dateType", and "allCallibrations" is defined to occur only once, so it ignores all subsequent instances of the element. In other words, your return message does not match the complex type definition from the WSDL.
To match the message, the complex type definition should be:
<complexType name="History">Or alternatively, to match the WSDL, the message should look something like:
<sequence>
<element name="lastCalibration" nillable="true" type="xsd:dateTime"/>
<element name="nextCalibration" nillable="true" type="xsd:dateTime"/>
<element name="allCalibrations" nillable="true" type="xsd:dateTime" maxOccurs="unbounded"/>
...
</sequence>
</complexType>
<soapenv:Body>
<getHistoryResponse xmlns="">
<ns1:getHistoryReturn xmlns:ns1="http://mdmonitor.webservice.qsgrimm.de">
<ns1:lastCalibration xsi:type="xsd:date">2002-09-11 </ns1:lastCalibration>
<ns1:nextCalibration xsi:type="xsd:date">2002-09-11</ns1:nextCalibration>
<ns1:allCalibrations xsi:type="impl:ArrayOf_xsd_dateTime" >
<ns1:dateTime xsi:type="xsd:date">1996-08-03</ns1:dateTime>
<ns1:dateTime xsi:type="xsd:date">1997-09-16</ns1:dateTime>
<ns1:dateTime xsi:type="xsd:date">1999-11-02</ns1:dateTime>
<ns1:dateTime xsi:type="xsd:date">2001-02-09</ns1:dateTime>
<ns1:dateTime xsi:type="xsd:date">2002-09-11</ns1:datetime>
</ns1:allCalibrations>
...
</ns1:getHistoryReturn>
</getHistoryResponse>
</soapenv:Body>
That's, of course assuming that you defined "impl:ArrayOf_xsd_dateTime" as an array of "ns1:dateTime" elements.
Note also that your soap message is not valid because the "getHistoryResponse" element is unqualified.
Perhaps you could provide a little more information (complete WSDL, WSDD, the methodology you used to implement the WSDL, WSDD, client, and server, etc). Also, what version of Axis are you using?
Anne
On 6/6/06, Artur Kraft <[EMAIL PROTECTED]> wrote:Hello all,
due to the fact that I don't have a clue, what to do to solve my axis problem, I have to bring this topic once again up. Hopefully someone can point me in the right direction.
thanks.
Artur
I encountered a problem with the client of my axis web service, but I could also be a problem on the server side. A "Date[]" array is beeing transferred and the browser shows the fields correctly (as long as I can tell), but the client receives only one element instead of five. Something with the WSDL typeMapping or the axis client generation is malfunctioning, I would suggest.
Three questions arise:
1) Why don't get all Dates from the SOAP xsd:dateTime elements transferred into the date array on client-side?
2) Why is so much manual customization required?
3) Am I doing something wrong in my development process?
In the following I provide the necessary information related to this issue:
The service has a "History" class as part of the Interface(History class shown below), which has a "java.util.Date[]" field called "allCalibrations".
class History (web service):
import java.util.Date;
public class History {
public Date lastCalibration = null;
public Date nextCalibration = null;
public Date[] allCalibrations = null;
...
}
If the client sends its request, the response in the browser looks fine (SOAP Message shown below), it shows the five dates from the allCalibrations Date[] field.
SOAP Response of the web service request "getHistory" (browser):
<?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>
<getHistoryResponse xmlns="">
<ns1:getHistoryReturn xmlns:ns1="http://mdmonitor.webservice.qsgrimm.de">
<ns1:lastCalibration xsi:type="xsd:date">2002-09-11</ns1:lastCalibration>
<ns1:nextCalibration xsi:type="xsd:date">2002-09-11</ns1:nextCalibration>
<ns1:allCalibrations xsi:type="xsd:date">1996-08-03</ns1:allCalibrations>
<ns1:allCalibrations xsi:type="xsd:date">1997-09-16</ns1:allCalibrations>
<ns1:allCalibrations xsi:type="xsd:date">1999-11-02</ns1:allCalibrations>
<ns1:allCalibrations xsi:type="xsd:date">2001-02-09</ns1:allCalibrations>
<ns1:allCalibrations xsi:type="xsd:date">2002-09-11</ns1:allCalibrations>
...
</ns1:getHistoryReturn>
</getHistoryResponse>
</soapenv:Body>
</soapenv:Envelope>
The web service WSDL, "History" complex type:
<complexType name="History">
<sequence>
<element name="lastCalibration" nillable="true" type="xsd:dateTime"/>
<element name="nextCalibration" nillable="true" type="xsd:dateTime"/>
<element name="allCalibrations" nillable="true" type="impl:ArrayOf_xsd_dateTime"/>
...
</sequence>
</complexType>
The cause of the client only receiving a one field Date object in the allCalibrations field could be due to "deploy.wsdd"-file manipulations. Generating a wsdl file from the web service interface results in many typeMappings like the following. But a "de.qsgrimm.webservice.mdmonitor.GetJobs" class doesn't exist, so I removed all those entries.
TypeMapping, automatically generated by axis (manually removed):
<typeMapping
xmlns:ns="http://mdmonitor.webservice.qsgrimm.de"
qname="ns:>getJobs"
type="java:de.qsgrimm.webservice.mdmonitor.GetJobs"
serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
encodingStyle=""
/>
One entry was due to the Date array in the History class. The Mapping was the following:
ArrayTypeMapping, automatically generated by axis:
<arrayMapping
xmlns:ns="http://mdmonitor.webservice.qsgrimm.de"
qname="ns:ArrayOf_xsd_dateTime"
type="java:java.util.Calendar[]"
innerType="cmp-ns:dateTime" xmlns:cmp-ns="http://www.w3.org/2001/XMLSchema"
encodingStyle=""
/>
But leaving the above statement in the deploy.wsdd, the field allCalibrations(Date[]) maps on client-side to:
private java.lang.Object[] allCalibrations;
Removing also the dateTime array mapping, results in a correct client-side-mapping as:
private java.util.Calendar[] allCalibrations;
but this configuration of History results in an exception thrown:
- Could not convert java.util.Date to bean field 'allCalibrations', type [Ljava.util.Calendar;
- Exception:
java.lang.IllegalArgumentException: argument type mismatch
at org.apache.axis.encoding.ser.BeanPropertyTarget.set(BeanPropertyTarget.java:157)
...
So, I altered the History class on the client-side by hand to the following for the client to function properly. But it seems as only a (bad) workaround to me.
private java.util.Date[] allCalibrations;
while lastCalibration and nextCalibration last as:
java.util.Calendar xCalibration
...which seems to me quite weird, but functional.
Again the three questions:
1) Why don't get all Dates from the SOAP xsd:dateTime elements transferred into the date array on client-side?
2) Why is so much manual customization required?
3) Am I doing something wrong in my development process?
Thanks a lot for your help!
kind regards
Artur
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
