Eclipse+axis2+tomcat 开发WebService示例
一.不能使用package关键字发布方法
1. 安装tomcat5.5,下载axis2-1.5-war.zip.
2. 将axis2-1.5-war.zip解压后,取axis2.war放到Tomcat 5.5的安装目录的webapps目录下。
3. 打开Eclipse,新建一个类,如evangelService,不能使用package关键字声明包。如:选择src,然后在那里新建一个Class这时候就采用缺省package也就没有package声明.
public classevangelService
{
public String getAddress(String name)
{
return "你好" + name + " 这里是深圳市南山区南山数字文化产业基地大厦西座";
}
}
4. 将程序编译后的Class文件拷贝到Tomcat5.5\webapps\axis2\WEB-INF\pojo下。如果没有pojo文件夹则新建一个。
5. 启动Tomcat,打开IE输入:http://localhost:8080/axis2/services/listServices,可以看见上面程序已经成功发布。
6.调用服务。将Tomcat5.5\webapps\axis2\WEB-INF\lib里的包,做成一个UserLibraries,并在调用的程序里引进来。在调用事件里写
try {
//使用RPC方式调用WebService
RPCServiceClientserviceClient = new RPCServiceClient();
Optionsoptions = serviceClient.getOptions();
//指定调用WebService的URL
EndpointReferencetargetEPR = new EndpointReference(
"http://localhost:8080/axis2/services/evangelService");
options.setTo(targetEPR);
//指定getAddress方法的参数值
Object[]opAddEntryArgs = new Object[] { "测试人员" };
//指定getAddress方法返回值的数据类型的Class对象
Class[]classes = new Class[] { String.class };
//指定要调用的getAddress方法及WSDL文件的命名空间
QNameopAddEntry = new QName("http://ws.apache.org/axis2", "getAddress");
//调用getAddress方法并输出该方法的返回值
System.out.println(serviceClient.invokeBlocking(opAddEntry, opAddEntryArgs,classes)[0]);
} catch (Exception ex) {
ex.printStackTrace();
}
运行程序后,就会打印出相应结果。
二.使用package关键字发布方法
1. 下载apache-tomcat-7.0.52, axis2-1.7.4-war.zip
2. 将axis2-1.7.4-war.zip解压后,去axis2.war放到tomcat的安装目录的webapps目录下。
3. 打开Eclipse, 创建一个普通java项目或者web项目都可,然后可以创建一个包名(包名可以随意取)
例子:
4. 将要发布的EvangelService.class,打包好,然后放到 yourTomca\webapps\axis2\WEB-INF\services
如图:
点击Next>
这一步把选择你的项目\src ,不过这里勾选默认是src下全部.class文件,也可以手动选择只勾选你要发布的webservice 类文件.
例如:
Select the export destination:
Jar file: C:\QMDownload\apache-tomcat-7.0.52\webapps\axis2\WEB-INF\services\evangel.jar
这里是选择你要放在哪个目录下(这里的目录最好是放在标红的路径下,不然放在其他路径还得从那个路径放到该路径下。因为下一步就是要配置一个services.xml 从这个路径下获取要发布的webservice), evangel.jar , jar包名字是可以任意取的.这里我取evangel为jar包名。
然后点击Finish即可。
5. 然后到C:\QMDownload\apache-tomcat-7.0.52\webapps\axis2\WEB-INF\services
标红的地址下新增一个services.xml文件在这个文件需要配置能访问到这个发布的 EvangelService.class,配置如下:
<service name="Evangel" > <!--name=服务名 -->
<description> Evangel </description> <!—这个服务的描述,可以随意填 -->
<messageReceivers>
<!--表示有参没有返回值的方法-->
<messageReceivermep="http://www.w3.org/ns/wsdl/in-only"class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
<!--表示有参有返回值的方法-->
<messageReceiver mep="http://www.w3.org/ns/wsdl/in-out" class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</messageReceivers>
<!-- 在这里用于设置发布的完整service名字(包名+类名)-->
<parametername="ServiceClass">com.webservice.EvangelService</parameter>
</service>
其中<service>元素用于发布 Web Service,一个 <service>元素只能发布一个 WebService 类,
name属性 表示 WebService名,如下面的 URL可以获得这个 WebService的 WSDL内容:
http://localhost:8080/axis2/services/Evangel?wsdl
其中name属性名就是上面 URL中"?"和 "/"之间的部分。
<description>元素表示当前 Web Service的描述,<parameter>元素用于设置 WebService的参数,在这里用于设置 WebService对应的类名。在这里最值得注意的是<messageReceivers>元素,该元素用于设置处理 WebService方法的处理器。例如, doAction方法有一个返回值,因此,需要使用可处理输入输出的RPCMessageReceiver类,而 update方法没有返回值,因此,需要使用只能处理输入的RPCInOnlyMessageReceiver类。
另外 services.xml文件中也可以直接指定WebService类的方法,如可以用下面的配置代码来发布 WebService(这种对于一个类中,2个以上方法时用这种配置,如不调用的方法就不需要在此配置),现在假设我们需要调用doAction、update。
配置如下:
<servicename="Evangel" >
<description>
Evangel
</description>
<operation name ="doAction" >
<messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
</operation >
<operation name ="update" >
<messageReceiver class ="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
</operation >
<parametername="ServiceClass">com.webservice.EvangelService</parameter>
</service>
如果想发布多个带包名的WebService,可以使用<serviceGroup>元素
例如我现在在com.webservice新添加了CrosslinkService类
配置services.xml如下:
<serviceGroup>
<service name="Evangel" >
<description> Evangel </description>
<operation name ="doAction" >
<messageReceiver class ="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</operation >
<operation name ="update" >
<messageReceiver class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
</operation >
<parametername="ServiceClass">com.webservice.EvangelService</parameter>
</service>
<service name="Crosslink" >
<description> Crosslink </description>
<messageReceivers>
<messageReceivermep="http://www.w3.org/ns/wsdl/in-only"class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
<messageReceiver mep="http://www.w3.org/ns/wsdl/in-out" class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</messageReceivers>
<parametername="ServiceClass">com.webservice.CrosslinkService</parameter>
</service>
</serviceGroup>
配置完成!
现在要把配置好的services.xml把它放进evangel.jar下的META-INF\services.xml(第一次打包是没有此文件的需要把配置好的丢进去),
如果不知道怎么打开.jar文件就下载一个解压缩软件,我这里用的【WinRAR】软件,如图所示:
然后基本配置的都好了,可以按【6】步骤去运行你发布好的webservice程序了。
PS: 开发中--因为程序开发过程可能需要多次打jar包。需要多次按图下操作。
否则缺少jar包中缺少services.xml文件则启动Tomcat时会
报出提示错误:
org.apache.axis2.deployment.DeploymentException: The services.xml file cannot be found for theservice:C:\QMDownload\apache-tomcat-7.0.52\webapps\axis2\WEB-INF\services\evangel.jar
则无法正常访问服务
6. 然后启动Tomcat, 打开任意浏览器输入:http://localhost:8080/axis2/services/listServices,可以看见上面程序已经成功发布。
Ps:ip地址和端口号是否跟示例一样,如不一样则改成你电脑配置的。还有如果访问不到根据tomcat报错提示跟踪并改正错误。
现在测试下调用发布的webservice,Evangel里的doAction方法
http://localhost:8080/axis2/services/Evangel/doAction?dataType=dept&xml=data
http://ip:port/axis2/services/ServiceName/MethodName?argName=value&(多个参数用&)args…
如果能正常访问则跟图中所示。
7. 代码调用服务。将Tomcat\webapps\axis2\WEB-INF\lib里的包,做成一个UserLibraries,并在调用的程序里引进来。在调用事件里写
/**
* RPCS (Remote Procedure Call System)远程过程调用<br>
* 调用已发布的WebService服务方法。</br>
* @param svcName :请求的服务名
* @param methodName : 请求调用的方法名
* @param parameterValue :参数值,如果有多个参数就传多个。
* @param returnTypes :指定返回的类型。
* @param feedback :调用方法成功后返回的data.
* @return :调用成功或失败
*/
@SuppressWarnings("rawtypes")
public static boolean invokeBlocking(StringserviceName,StringmethodName,
Object[] parameterValue,Class[]returnTypes,VariantHolder<Object>feedback) {
//使用RPC方式调用WebService
RPCServiceClient serviceClient =null;
String targeURL = "http://" + RPCClient.getIpAndPort() + "/axis2/services/" + serviceName + "/";
try {
serviceClient = new RPCServiceClient();
Options options = serviceClient.getOptions();
//指定调用WebService的URL
EndpointReference targeEPR = new EndpointReference(targeURL);
options.setTo(targeEPR);
//指定getGreeting方法的的参数值
Object[] parameterValues = parameterValue;
//指定getGreeting方法返回值的数据类型的Class对象
Class[] retTypes = returnTypes;
//指定要调用的getGreeting方法及WSDL文件的命名空间
String targetNamespace = RPCClient.getTargetNamespace();
/*
* QName构造方法
* 第一个参数是WSDL文件的命名空间名,
* 也就是<wsdl:definitions>元素的targetNamespace属性值,
* 第二个参数是需要调用webService的方法名。
*/
QName opName = new QName(targetNamespace,methodName );
/*
* 第一个参数的类型是QName对象,表示要调用的方法名;
* 第二个参数表示要调用的WebService方法的参数值,参数类型为Object[];
* 第三个参数表示WebService方法的返回值类型的Class对象,参数类型为Class[]。
* 当方法没有参数时,invokeBlocking方法的第二个参数值不能是null,而要使用new Object[]{}。
*/
feedback.value = serviceClient.invokeBlocking(opName,parameterValues,retTypes)[0];
return true;
} catch (AxisFaulte) {
e.printStackTrace();
} catch (Exceptione) {
e.printStackTrace();
}
return false;
}
private static String ipAndPort;
private static String targetNamespace;
public static StringgetIpAndPort() {
return ipAndPort;
}
public static String getTargetNamespace() {
returntargetNamespace;
}
public static void setConfig(String ipAndPort,String targetNamespace) {
try {
if (null ==ipAndPort ||"".equals(ipAndPort)) {
throw new Exception(String.format("【%s】无效的ip或端口",ipAndPort));
}
if (null ==targetNamespace ||"".equals(targetNamespace)){
throw new Exception(String.format("【%s】错误的命名空间",targetNamespace));
}
RPCClient.ipAndPort =ipAndPort;
RPCClient.targetNamespace =targetNamespace;
} catch(Exceptione) {
e.printStackTrace();
}
}
//调用服务
@SuppressWarnings("rawtypes")
public static void main(String[] args) {
Object[] parameterValue = { "dept", "SZ0001" };
Class[] returnTypes = { String.class };
VariantHolder<Object> feedback =new VariantHolder<Object>();
RPCClient.setConfig("192.168.0.97:8080","http://controller.in.yongyou.threecolor.com");
RPCClient.invokeBlocking("Evangel","doAction",parameterValue,returnTypes,feedback);
System.out.println(feedback.value);
}
道讯开发与部署axis2WEB Serivce服务中需要注意的事项
开发
1. 正常开发如果项目中需要用到什么包,都在项目中配置完之后,配置一份到apache-tomcat-7.0.52\webapps\axis2\WEB-INF\lib 下。
例如我开发的一个项目webservice项目中用到了XStream。则需要将相应的
这几个包都放在apache-tomcat-7.0.52\webapps\axis2\WEB-INF\lib下。
不然会发生在项目编译期无报错现象,可调式、运行程序中报类似找不到xxx类异常。
还有像我们公司用的RMI服务调用本地、远程接口,在这个服务层我们需要先启动公司中的Server。
所以要在Debug Configurations窗口配置,因为开发yongyu项目中用的axis2+tomcat 发布webService但是在调用的远程、本地接口一直找不到xxx类,
后来发现在【Server】里需要配置如下:
才可正常使用RMI调用远程、本地接口。
部署
webservice服务程序开发完之后,最好将apache-tomcat-7.0.52\webapps\axis2\WEB-INF\servicesevangel.jar包改成evangel.aar
其实用jar包,aar包发布都可,但是官方说明正常发布最好用.aar发布比较好,
所以开发过程中为了不用每次打完jar包,还要修改成.aar后缀。所以在开发完要正式部署后修改成.aar即可。
最后开发完后需要将开发好程序复制一份到公司程序的[bin]目录下(即Server.bat同目录下),然后需要在Server.bat刚复制的jar包, 例如:yongyu.jar。一般我会放最后,这个看实际情况
著作:ALEX