自动部署Axis 1.4 Web Service的ANT脚本

Posted on February 7, 2007

0


这几天一直在忙着写一个能够自动编译,打包部署Web Service的ANT脚本。编译打包这些都很简单,难得是如何让Axis自动生成WSDD部署文件而尽量不用改动已有的Web Service代码。这里面出现了不少问题,绝大部分问题是和.NET交互的问题。现在才发现Axis真是Bug多多。废话不说了,就show一下2段脚本。

<target name="prepare-deploy" >
  <delete dir="${deployPrepareDir}"/>
  <mkdir dir="${deployPrepareDir}"/>
  <for param="service">
   <path>
    <fileset dir="${projectWebLocalDir}/${classesDir}" includes="**/*Service.class"/>
   </path>
   <sequential>
    <mkdir dir="${deployPrepareDir}\${srcDir}"/>
    <!--Regular expression used here to determine the service class. -->
    <propertyregex override="yes" property="wholeClassNameTemp" input="@{service}" 
         regexp="classes\\([^\.]*)\.class" select="\1" casesensitive="false"/>
    <propertyregex override="yes" property="wholeClassName" input="${wholeClassNameTemp}" 
         regexp="\\" replace="\." casesensitive="false"/>
    <propertyregex override="yes" property="className" input="@{service}" 
         regexp="classes\\com\\CDRator\\soap\\([^\.]*)\.class" select="\1" 
         casesensitive="false"/>
    <mkdir dir="${deployPrepareDir}\${className}"/>
    <axis-java2wsdl classname="${wholeClassName}" style="${wsStyle}" 
         use="${wsEncode}" namespace="${wsTNS}" 
         location="http://${tomcatServerHost}:${tomcatServerPort}/
                           ${webApplicationRoot}/services/${className}" 
         output="${deployPrepareDir}\main.wsdl">
     <classpath>//放编译好的Web Service实现jar</classpath>
    </axis-java2wsdl>
    <axis-wsdl2java output="${deployPrepareDir}\${srcDir}" verbose="false" 
        url="${deployPrepareDir}\main.wsdl" serverside="true" debug="false">
     <classpath>
      <fileset dir="${projectWebLocalDir}\" includes="**.jar"/>
      <fileset dir="${projectLocalDir}\" includes="**.jar"/>
      <fileset dir="${webShopLocalDir}\" includes="**.jar"/>
      <fileset dir="${ratorLocalDir}\" includes="**.jar"/>
      <fileset dir="${ratorLocalDir}\${libDir}" includes="activation.jar"/>
     </classpath>
     <!-- <mapping namespace="${wsTNS}" package="com.CDRator.soap.data"/> -->
    </axis-wsdl2java>
    <copy todir="${deployPrepareDir}\${className}">
     <fileset dir="${deployPrepareDir}\${srcDir}\com\CDRator\soap">
      <include name="*deploy*.wsdd"/>
     </fileset>
    </copy>
    <delete>
     <fileset dir="${deployPrepareDir}\${srcDir}\com\CDRator\soap">
      <include name="*deploy*.wsdd"/>
     </fileset>
    </delete>
    <delete file="${deployPrepareDir}\main.wsdl"/>
     <replaceregexp file="${deployPrepareDir}\${className}\deploy.wsdd" 
         match="com.CDRator.soap.${className}SoapBindingImpl" 
         replace="com.CDRator.soap.${className}"/>
     <replaceregexp flags="g" byline="false" 
          file="${deployPrepareDir}\${className}\deploy.wsdd" 
          match="&lt;(type|array)Mapping\r(\s*)xmlns:ns(.*)\r(\s*)([^\.]*)&quot;ns:&gt;
         ([^\.]*)&quot;(.*)\r(\s*)(.*)\r(\s*)(.*)\r(\s*)(.*)\r(\s*)\/&gt;" 
     replace=""/> 
    <sleep seconds="2"/>
    </sequential>
  </for>
  <mkdir dir="${deployPrepareDir}\${classesDir}"/>
   <javac srcdir="${deployPrepareDir}\${srcDir}" destdir="${deployPrepareDir}\${classesDir}"
       debug="true" nowarn="false" target="1.4" 
       memoryInitialSize="80m" memoryMaximumSize="256m" 
       fork="true" executable="${javaCompiler}">
    <include name="**/**"/>
    <classpath>
     <fileset dir="${projectWebLocalDir}\${libDir}" includes="**/*.jar"/>
     <fileset dir="${ratorLocalDir}\" includes="${ratorJarFileName}"/>
    </classpath>
   </javac>
   <jar destfile="${deployPrepareDir}/${wsClientJarFileName}" 
         basedir="${deployPrepareDir}\${classesDir}\"/>
  </target>
   <target name="deploy-webService">
   <for param="service">
    <!--<dirset dir="${deployPrepareDir}">
     <exclude name="${srcDir}**"/>
     <exclude name="${classesDir}**"/>
    </dirset> -->
         <path>
     <fileset dir="${projectWebLocalDir}/${classesDir}" includes="**/*Service.class"/>
    </path>
    <sequential>
     <propertyregex override="yes" property="className" 
        input="@{service}" regexp="classes\\com\\CDRator\\soap\\([^\.]*)\.class" select="\1" 
        casesensitive="false"/>
     <axis-admin url="${axisAdminURL}" 
        xmlfile="${deployPrepareDir}\${className}\undeploy.wsdd" debug="true"/>
     <axis-admin url="${axisAdminURL}" 
        xmlfile="${deployPrepareDir}\${className}\deploy.wsdd" debug="true"/>
    </sequential>
   </for>
  </target>

这段脚本全自动寻找classpath中后缀为*Service.class的类,然后运行Java2WSDL -> WSDL2Java命令。因为是Wrapped的Service,生成的Wrapper定义需要从WSDD里面删除,否则就得把client一并部署,但在某些情况下会出现找不到类的情况。所以我建议还是直接删除所有带ns:>的typeMapping/arrayMapping。此外实现类需要用regular express替换成真正的实现类。如果这2部正确执行的话,就可以不用添加任何class到war文件里了。

客户端是.NET的话,一定要小心,最好把所有element放在同一个namespace下面,似乎Axis有个Bug,会把element都放在TargetNameSpace下面,日。最简单的做法就是把所有在WSDD部署文件的name space都替换掉:

 <replaceregexp flags="g" file="${deployPrepareDir}\${className}\deploy.wsdd" 
         match="http://data.soap.CDRator.com" replace="http://soap.CDRator.com"/>

Posted in: Development