axis-java-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Artur Kraft <kra...@darkfluid.com>
Subject Re: [Axis v1.4] typeMapping or client-side class generation problem
Date Wed, 07 Jun 2006 14:49:58 GMT
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:
_

   1. 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;
      }
   2. 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
   3. 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
   4. 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"
   5. Copy the compiled web service java classes to the dir
      "%AXIS_HOME%\WEB-INF\classes".
   6. Deploy the service using AdminClient and modified deploy.wsdd
      (attached "deploy.edited.wsdd")
   7. 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
   8. Invoke the client using https/SSL.

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?


 > 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 regards
Artur



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">
>   <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>
>
> Or alternatively, to match the WSDL, the message should look something 
> like:
>
>    <soapenv:Body>
>       <getHistoryResponse xmlns="">
>         <ns1:getHistoryReturn 
> xmlns:ns1="http://mdmonitor.webservice.qsgrimm.de" 
> <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* <krabat@darkfluid.com 
> <mailto:krabat@darkfluid.com>> 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/"
>     <http://schemas.xmlsoap.org/soap/envelope/>
>     xmlns:xsd="http://www.w3.org/2001/XMLSchema"
>     <http://www.w3.org/2001/XMLSchema>
>     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>     <http://www.w3.org/2001/XMLSchema-instance>>
>         <soapenv:Body>
>           <getHistoryResponse xmlns="">
>             <ns1:getHistoryReturn
>     xmlns:ns1="http://mdmonitor.webservice.qsgrimm.de"
>     <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"
>     <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"
>     <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"
>     <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
>
>
>

Mime
View raw message