一、建立要发布的Web Service
?
1.1 解压所下载的axis2-1.6.0-bin.zip,在Eclipse中的Windows\Preferences下new一个User Libraries,命名为axis2,将解压后文件夹中 axis2-1.6.0\lib 下的包均添加进来。这一步操作的目的是为了以后工程方便添加axis2所需的 jar文件。
1.2 建立一个JavaProject,命名为sayHello,将axis2用户库加入到build path中
1.3 现在开始编写要发布的WebService,在src包中建包Hi,建立Hello类如下:
package Hi; publicclass Hello { public String sayHello(String user) { return"Hello, "+ user; } }
?此时sayHello工程结构如下:
二、发布Web Service
2.1 编译刚刚建立的Hello类,类编译后,会在workspace中对应工程目录下的bin文件夹下生成Hello.class文件
2.2 打包要发布的Service, 点击Eclipse中New ――> File ――> Other ――> Axis2 wizards ――> Axis2 Services Archiver,按照向导选择刚建立的类编译后的class文件。
注意点:
1、在我的工程中,workspace是D:\eclipse-sdk\sdkProject,选择class目录,本工程中class Hello是带包Hi的,因此我们不能选成D:\eclipse-sdk\sdkProject\sayHello\bin\Hi,而应该选择D:\eclipse-sdk\sdkProject\sayHello\bin,如图所示:
2、默认选择Skip WSDL
3、继续next,这两步默认,什么都不选
4、设定服务名称和所使用的类名,点击Load如下所示:
注意Class name请务必设为Hi.Hello,代表使用的类是D:\eclipse-sdk\sdkProject\sayHello\bin路径下,文件夹Hi下的Hello类,否则Load不上的。
5 设置输出路径为: D:\tomcat7\webapps\axis2\WEB-INF\services
6 点击Finish完成发布。
?
?
三、测试所发布的Web Service
?
打开http://localhost:8080/axis2/services/listServices页面,可以看到sayHello服务:
?
点击进到sayHello的wsdl页面:http://localhost:8080/axis2/services/sayHello?wsdl,表明服务部署正确。
四、编写客户端代码调用WebService
本文例子与其他例子最大的不同就在这里,其他例子一般需要根据刚才的服务wsdl生成客户端stub,然后通过stub来调用服务,这种方式显得比较单一,客户端必须需要stub存根才能够访问服务,很不方面。
本例子的客户端不采用stub方式,而是一种实现通用的调用方式,不需要任何客户端存根即可访问服务。只需要指定对于的web servce地址、操作名、参数和函数返回类型即可。工程结构如下:
代码如下:
package Hi; import javax.xml.namespace.QName; import org.apache.axis2.AxisFault; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.Options; import org.apache.axis2.rpc.client.RPCServiceClient; publicclass myClient { private RPCServiceClient serviceClient; private Options options; private EndpointReference targetEPR; public myClient(String endpoint) throws AxisFault { serviceClient =new RPCServiceClient(); options = serviceClient.getOptions(); targetEPR =new EndpointReference(endpoint); options.setTo(targetEPR); } public Object[] invokeOp(String targetNamespace, String opName, Object[] opArgs, Class<?>[] opReturnType) throws AxisFault, ClassNotFoundException { // 设定操作的名称 QName opQName =new QName(targetNamespace, opName); // 设定返回值 //Class<?>[] opReturn = new Class[] { opReturnType }; // 操作需要传入的参数已经在参数中给定,这里直接传入方法中调用 return serviceClient.invokeBlocking(opQName, opArgs, opReturnType); } /** * @param args * @throws AxisFault * @throws ClassNotFoundException */ publicstaticvoid main(String[] args) throws AxisFault, ClassNotFoundException { // TODO Auto-generated method stub final String endPointReference ="http://localhost:8080/axis2/services/sayHello"; final String targetNamespace ="http://Hi"; myClient client =new myClient(endPointReference); String opName ="sayHello"; Object[] opArgs =new Object[]{"My Friends"}; Class<?>[] opReturnType =new Class[]{String[].class}; Object[] response = client.invokeOp(targetNamespace, opName, opArgs, opReturnType); System.out.println(((String[])response[0])[0]); } }
?运行该程序,点击Run As->Java application,可以看到控制台端口的输出是:Hello, My Friends,表明客户端调用成功。
??? 该例子最大的不同和优势表现在客户端的调用方式,或者说是发起服务调用的方式,虽然比起客户端stub存根的方式,代码稍多,但是这种方式统一,不需要生产stub存根代码,解决了客户端有很多类的问题。如果读者对这些代码进一步封装,我想调用方式很简单,只需要传递相关参数,这更好地说明了服务调用的优势。而且这种方式更加简单明了,一看便知具体含义。而不需要弄得stub类的一些机制。
?