最近研究Axis。前几天写了一篇使用myEclipse,tomcat 和Axis发布webService ,当时受了公司某些“java过来人”的误导,说用Axis来创建Webservice,只能写先wsdl,再使用WSDL2Java方法来创建Webservice。我就稀里糊涂地想,那多麻烦啊,我想写个Webservice敢情得先写个wsdl吗?有没有直接把我写的类转成wsdl的方法?后来一看,嗨,Axis还真有个Java2WSDL方法。于是乎,我就先写类,然后Java2WSDL生成wsdl,然后WSDL2Java再生成Webservice。。。。。。居然很成功,测试也没问题,就大摇大摆放到博客上去了
。
今天再一想,不对呀。。。。。我想修改Webservice,新增或者修改方法怎么办?难不成再生成一次wsdl然后再折腾回去?
我就想,Axis不就一框架嘛,框架这东西,一般只要写好某个配置文件不就ok了吗?干吗要手工运行那么多脚本和命令?
最后终于被我找到关键点,也就是wsdd文件,特撰文如下(上篇文章不删了,全当告诉大伙Axis里还有个Java2WSDL的玩意儿):
一.准备工作:
1. 安装Axis。去官方网站http://ws.apache.org/axis/下载axis包,然后解压到任何一个目录。本例使用的是axis-bin-1_4.tar.gz ,解压到E:\axis-bin-1_4\axis-1_4。
2. 开发环境准备。本例使用MyEclipse6.0 ,web server使用tomcat6。
二.创建Web工程:
1. MyEclipse中新建web工程,名称为TestCustomAxis。工程目录为:D:\JavaProject\TestCustomAxis。
2. 引入axis包: 把axis目录下的E:\axis-bin-1_4\axis-1_4 \lib\下的所有jar包拷贝到工程下面的WebRoot\WEB-INF\lib下,MyEclipse会自动添加到引用库(Referenced Libraries):

三.写接口和类代码:
1.这里我想顺便测试一下Axis是否支持对复杂对象的串行化,于是自定义一个wsResult类(注意这个类一定要是标准写法,属性有get,set方法),代码如下:
package
com.ckp;
public
class
wsResult {
private
int
errorCode;
private
String errorString;
private
String resultVal;
public
wsResult(){
this
.errorCode
=
0
;
this
.errorString
=
""
;
this
.resultVal
=
""
;
}
public
int
getErrorCode() {
return
errorCode;
}
public
void
setErrorCode(
int
errorCode) {
this
.errorCode
=
errorCode;
}
public
String getErrorString() {
return
errorString;
}
public
void
setErrorString(String errorString) {
this
.errorString
=
errorString;
}
public
String getResultVal() {
return
resultVal;
}
public
void
setResultVal(String resultVal) {
this
.resultVal
=
resultVal;
}
}
2.定义接口SayHelloService,所属包是com.ckp:
package
com.ckp;
public
interface
SayHelloService {
public
String sayHelloMr(String name);
public
wsResult sayHelloMiss(String name);
}
3.创建实现类SayHelloImpl,实现接口SayHelloService:
package
com.ckp;
public
class
SayHelloImpl
implements
SayHelloService{
public
String sayHelloMr(String name){
return
"
Hello you,,,Mr.
"
+
name;
}
public
wsResult sayHelloMiss(String name){
wsResult retObj
=
new
wsResult();
retObj.setResultVal(
"
Hello,Miss
"
+
name);
return
retObj;
}
}
工程结构如下图:

四.配置Axis:
1.修改web.xml文件,没什么特殊要求的话,可以直接把axis压缩包(E:\axis-bin-1_4\axis-1_4\webapps\axis\WEB-INF\)里的web.xml拷贝过来覆盖工程的web.xml。
2.书写deploy.wsdd,这是关键步骤。在任意位置创建文件deploy.wsdd(比如创建到E:\)。内容如下,具体配置见注释文字:
<
deployment
xmlns
="http://xml.apache.org/axis/wsdd/"
xmlns:java
="http://xml.apache.org/axis/wsdd/providers/java"
>
<!--
Services from TestAxisService WSDL service
-->
<
service
name
="TestAxisService"
provider
="java:RPC"
style
="wrapped"
use
="literal"
>
<!--
服务名称,自己定义. provider="java:RPC"或者provider="java:MSG",style :RPC, DOCUMENT or WRAPPED ,use: LITERAL or ENCODED...具体含义参见:http://ws.apache.org/axis/java/reference.html
-->
<
parameter
name
="wsdlTargetNamespace"
value
="http://ckp.com"
/>
<!--
将显示在wsdl上的命名空间 ,自己定义
-->
<
parameter
name
="wsdlServiceElement"
value
="ckpService"
/>
<!--
将显示在wsdl中wsdl:service节点的 name属性, 自己定义
-->
<
parameter
name
="schemaQualified"
value
="http://ckp.com/scheme/1.0"
/>
<!--
scheme命名空间限制,自己定义
-->
<
parameter
name
="wsdlServicePort"
value
="testCustomAxis"
/>
<!--
将显示在wsdl中wsdl:port节点的 name属性, 自己定义
-->
<
parameter
name
="className"
value
="com.ckp.SayHelloImpl"
/>
<!--
实现类名,要带上包名
-->
<
parameter
name
="wsdlPortType"
value
="SayHelloService"
/>
<!--
接口名
-->
<
parameter
name
="typeMappingVersion"
value
="1.2"
/>
<!--
下面就是对方法的描述了,要写对方法的名字,返回值类型和参数的名字和类型。
-->
<!--
请注意参数:xmlns:operNS是scheme的targetNamespace属性
-->
<!--
请注意参数 :xmlns:rtns要按返回值的类型(returnType)相应填写
-->
<
operation
name
="sayHelloMr"
qname
="operNS:sayHelloMr"
xmlns:operNS
="http://ckp.com/scheme/1.0"
returnQName
="retNS:out"
xmlns:retNS
="http://ckp.com/scheme/2.0"
returnType
="rtns:string"
xmlns:rtns
="http://www.w3.org/2001/XMLSchema"
soapAction
=""
>
<!--
请注意参数 :xmlns:tns要按输入参数的类型(type)相应填写
-->
<
parameter
qname
="pns:name"
xmlns:pns
="http://ckp.com/scheme/1.0"
type
="tns:string"
xmlns:tns
="http://www.w3.org/2001/XMLSchema"
/>
</
operation
>
<!--
注意这个方法里的xmlns:rtns ,是返回类型的命名空间,因为里面有我们自定义的wsResult类型,所以指定为http://ckp.com/scheme/1.0
-->
<
operation
name
="sayHelloMiss"
qname
="operNS:sayHelloMiss"
xmlns:operNS
="http://ckp.com/scheme/1.0"
returnQName
="retNS:out"
xmlns:retNS
="http://ckp.com/scheme/2.0"
returnType
="rtns:wsResult"
xmlns:rtns
="http://ckp.com/scheme/1.0"
soapAction
=""
>
<
parameter
qname
="pns:name"
xmlns:pns
="http://ckp.com/scheme/1.0"
type
="tns:string"
xmlns:tns
="http://www.w3.org/2001/XMLSchema"
/>
</
operation
>
<
parameter
name
="allowedMethods"
value
="sayHelloMr sayHelloMiss"
/>
<!--
value里面用空格隔开方法名
-->
<!--
串行化的关键就在下面这里了,对自定义类型wsResult的描述。。。注意type属性里要带上包名,命名空间最好与上面返回类型的xmlns:rtns一致
-->
<
typeMapping
xmlns:ns
="http://ckp.com/scheme/1.0"
qname
="ns:wsResult"
type
="java:com.ckp.wsResult"
serializer
="org.apache.axis.encoding.ser.BeanSerializerFactory"
deserializer
="org.apache.axis.encoding.ser.BeanDeserializerFactory"
encodingStyle
=""
/>
</
service
>
</
deployment
>
3.把web工程部署到tomcat,启动tomcat。
4.生成server-config.wsdd文件,步骤如下:
1)新建makeWsdd.bat,内容如下
set Axis_Lib
=
E:\ axis
-
bin
-
1_4\axis
-
1_4\lib
set Java_Cmd
=
java
-
Djava.ext.dirs
=%
Axis_Lib
%
set Axis_Servlet
=
http:
//
localhost:
8080
/
TestCustomAxis
/
services
/
AdminService
%
Java_Cmd
%
org.apache.axis.client.AdminClient
-
l
%
Axis_Servlet
%
E: \deploy.wsdd
写对axis包的路径和刚才手写的deploy.wsdd路径,以及webserver服务地址。
2)命令行下,执行makeWsdd.bat:(注意此步骤进行时tomcat必需是启动状态):
执行成功会显示如下信息:
在apache-tomcat-6.0.14\webapps\TestCustomAxis\WEB-INF\下也会出现server-config.wsdd文件。
5.重启tomcat。
五.测试Webservice:
1.先测试wsdl,浏览器输入:http://localhost:8080/TestCustomAxis/services:

点击TestAxisService的wsdl,查看wsdl文件,可以看到,自定义类型wsResult的串行化也成功了:

2.测试服务是否正确执行:我们用Myeclipse自带的测试工具来测试:
1)打开Myeclipse里的Web Services Explorer:

2)弹出如下界面,选择右上角的WSDL Page :

3)显示如下,地址栏输入我们的wsdl地址,点击 Go:

4)显示如下,可以点击方法1或者方法2进入测试某个方法:

5)点击方法1,进入如下界面,随便输入参数”奥巴马”,点击Go,下放显示结果Hello you,,,Mr.奥巴马 。

6)点击方法2,进入如下界面,随便输入参数” 布兰妮”,点击Go,下放显示结果,可以看到自定义的wsResult类正确被串行化的结果:

总结:与Xfire相比,用Axis写Webservice稍微复杂些,不过还是很简单地。建工程,写接口,写类,拷贝一个web.xml,写deploy.wsdd ,生成server-config.wsdd,万事ok!
弄明白如何手工写wsdd文件的好处是,灵活性比较大,如果以后想对Webservice修改或者添加方法。直接修改server-config.wsdd文件即可(server-config.wsdd文件里有一段内容,与deploy.wsdd配置内容一样,照着修改即可。官网上说,在部署服务时,你甚至可以把官方例子上的server-config.wsdd文件拷贝过来,手动修改即可,无需像本文一样用deploy.wsdd来生成。由于server-config.wsdd文件内容太多太复杂,我这里使用内容较少的deploy.wsdd来生成它,比较容易理解)。
六.关于部署到websphere
跟普通项目一样,打WAR包,部署到websphere,然后把server-config.wsdd文件拷贝到工程下的WEB_INF文件夹下即可。如果不需要附件功能,可以删掉server-config.wsdd文件的如下节点:
<
parameter
name
="attachments.Directory"
value
="C:\Program Files\Apache Software Foundation\apache-tomcat-6.0.14\webapps\TestCustomAxis\WEB-INF\attachments"
/>