If you are handling a legacy system, using Axis (1.4) webservices you must have come across Java2WSDL and WSDL2Java tools. The tools help you to generate a WSDL from a java class as well as generating stubs/skeletons from a WSDL. However if are dealing with <code>java.util.Date</code> fields in your code, you should notice following :
package com.aminur.test.ws.axis1.dateservice; import java.util.Date; public abstract class TestService { public abstract Date fetchEndDate(); public void updateEndDate(Date dateToBeSet) { } }
Now if you will use Java2WSDL like below :(ignore the variables in the attribute. Entire project is attached in end of post)
<target name="generate-wsdl" depends="init"> <mkdir dir="wsdl" /> <delete file="wsdl/${wsdl.name}" /> <axis-java2wsdl classname="${basepackage}.TestService" style="wrapped" namespace="${service.namespace}" output="wsdl/${wsdl_nocustomize.name}" location="http://localhost:5000/services/TestConfiguration" porttypename="TestConfiguration" serviceelementname="TestService"> <classpath refid="library.classpath" /> </axis-java2wsdl> </target> </textarea> <font color="navy">you will find wsdl as something like below: <textarea name="code" class="xml" cols="80" rows="15"> <element name="fetchEndDate"> <complexType/> </element> <element name="fetchEndDateResponse"> <complexType> <sequence> <element name="fetchEndDateReturn" type="xsd:dateTime"/> </sequence> </complexType> </element> <element name="updateEndDate"> <complexType> <sequence> <element name="in0" type="xsd:dateTime"/> </sequence> </complexType> </element> <element name="updateEndDateResponse"> <complexType/> </element> </schema> </wsdl:types>
you will find wsdl as something like below:
<element name="fetchEndDate"> <complexType/> </element> <element name="fetchEndDateResponse"> <complexType> <sequence> <element name="fetchEndDateReturn" type="xsd:dateTime"/> </sequence> </complexType> </element> <element name="updateEndDate"> <complexType><span data-mce-type="bookmark" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" class="mce_SELRES_start"></span> <sequence> <element name="in0" type="xsd:dateTime"/> </sequence> </complexType> </element> <element name="updateEndDateResponse"> <complexType/> </element> </schema> </wsdl:types>
Notice the xsd type for the return or the parameter. It is dateTime. When this WSDL will be used in target WSDL2Java, then the datatype for the parameter/return type will be changed to java.util.Calendar.
You can change the generated wsdl file manually to replace dateTime with date. However in the automated build process this will be a bottleneck. What I did is customized this generated wsdl file with a xsl style sheet to replace the type of the element. Following is the style sheet I used.
<?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="1.0"> <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="node()|@*"> <xsl:choose> <!-- Axis 1 when generates wsdl from java, it converts xsd:date to xsd:datetime and that creates problem as then your WS interface will allow 2009-05-15T09:11:17 as valid entry. --> <xsl:when test="name()='element' and @type=('xsd:dateTime') and (@name=('fetchEndDateReturn') or @name=('dateToBeSet') )"> <element> <xsl:copy-of select="namespace::* | @*[name()!='type']" /> <xsl:attribute name="type">xsd:date</xsl:attribute> </element> </xsl:when> <!-- default behaviour is to copy the stuff --> <xsl:otherwise> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>
And following is the snippet from build.xml file which uses the xsl to replace dateTime with date.
<target name="generate-wsdl-with-customization" depends="compile_with_debug"> <mkdir dir="tmp" /> <mkdir dir="wsdl" /> <delete file="wsdl/${wsdl.name}" /> <axis-java2wsdl classname="${basepackage}.TestService" style="wrapped" namespace="${service.namespace}" output="tmp/${wsdl.name}" location="http://localhost:5000/services/TestConfiguration" porttypename="TestConfiguration" serviceelementname="TestService"> <classpath refid="library.classpath" /> </axis-java2wsdl> <xslt force="true" basedir="tmp" destdir="wsdl" extension=".wsdl" style="customize.xsl" includes="*.wsdl" /> <delete dir="tmp" /> </target>
The wsdl file snippet generated after customization (and after compiling the abstract class in debug mode) is as below
<element name="fetchEndDate"> <complexType/> </element> <element name="fetchEndDateResponse"> <complexType> <sequence> <element name="fetchEndDateReturn" type="xsd:date"/> </sequence> </complexType> </element> <element name="updateEndDate"> <complexType> <sequence> <element name="dateToBeSet" type="xsd:date"/> </sequence> </complexType> </element> <element name="updateEndDateResponse"> <complexType/> </element> </schema> </wsdl:types>
Now the last part remaining is the insertion of following code in your server-config.wsdd as child of your service. This is required, to assign the correct (De)Serializer to the element.
<typeMapping xmlns:ns="http://www.w3.org/2001/XMLSchema" qname="ns:date" type="java:java.util.Date" serializer="org.apache.axis.encoding.ser.DateSerializerFactory" deserializer="org.apache.axis.encoding.ser.DateDeserializerFactory" encodingStyle="" /><span data-mce-type="bookmark" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" class="mce_SELRES_start"></span>
Related posts
Feed
- India
- World
- Live
- Cricket News
To find out more, including how to control cookies, see here Cookie Policy