您的位置:首页 > 编程语言 > Java开发

WebServices学习笔记(二)用java编写WebService的客户端代码

2015-11-17 08:41 609 查看
转自:http://m.blog.csdn.net/blog/jiqiujia/37097249#

二、用java编写WebService的客户端代码

1. 使用RPC远程调用的方式

首先当然是引包,将(一)中下载的axis2-1.6.2-bin.zip解压,将lib目录下的所有jar包都引进去(其实并不需要所有的包,但是我也分不清楚哪些需要哪些不需要)

public static void RPCClient() throws Exception {
String url = "http://localhost:8080/axis2/services/SimpleService";
// 使用RPC方式调用WebService
RPCServiceClient serviceClient = new RPCServiceClient();
Options options = serviceClient.getOptions();
// 指定调用WebService的URL
EndpointReference targetEPR = new EndpointReference(url);
// 确定目标服务地址
options.setTo(targetEPR);
// 指定要调用的getGreeting方法及WSDL文件的命名空间
QName opAddEntry = new QName("http://ws.apache.org/axis2",
"getGreeting");
// 指定getGreeting方法的参数值
Object[] parameters = new Object[] { "World" };
// 指定getGreeting方法返回值的数据类型的Class对象
Class[] classes = new Class[] { String.class };

// 调用方法一 传递参数,调用服务,获取服务返回结果集
OMElement element = serviceClient.invokeBlocking(opAddEntry, parameters);
// 值得注意的是,返回结果就是一段由OMElement对象封装的xml字符串。
// 我们可以对之灵活应用,下面我取第一个元素值,并打印之。因为调用的方法返回一个结果
String result = element.getFirstElement().getText();
System.out.println(result);

classes = new Class[] { int.class };
opAddEntry = new QName("http://ws.apache.org/axis2", "getNum");
Object[] response = serviceClient.invokeBlocking(opAddEntry, new Object[] {},
classes);
System.out.println(response[0]);
}
创建工程运行上面代码后,如果能正确输出信息,则表示成功
上面的url如果换成http://localhost:8080/axis2/services/SimpleService?wsdl也能成功

在创建QName对象时,QName类的构造方法的第一个参数表示WSDL文件的命名空间名,也就是<wsdl:definitions>元素的targetNamespace属性值
invokeBlocking方法的第一个参数的类型是QName对象,表示要调用的方法名;第二个参数表示要调用的WebService方法的参数值,参数类型为Object[];第三个参数表示WebService方法的返回值类型的Class对象,参数类型为Class[]。当方法没有参数时,invokeBlocking方法的第二个参数值不能是null,而要使用new
Object[]{}。

如果被调用的WebService方法没有返回值,应使用RPCServiceClient类的invokeRobust方法,该方法只有两个参数,它们的含义与invokeBlocking方法的前两个参数的含义相同。

2. 使用document方式调用

public static void testDocument() throws Exception{
//应用document方式调用
String url = "http://localhost:8080/axis2/services/SimpleService";
Options options = new Options();
EndpointReference targetEPR = new EndpointReference(url);
ServiceClient client = new ServiceClient();
options.setTo(targetEPR);
client.setOptions(options);

OMFactory fac = OMAbstractFactory.getOMFactory();

/****************这一部分其实就是构造出一段xml:
* <nls:getGreeting xmlns:nls="http://ws.apache.org/axis2"><nls:name>world</nls:name></nls:getGreeting>
* **********************/
String ns = "http://ws.apache.org/axis2";
//nls就是命名空间的别名,可以没有
OMNamespace omNs = fac.createOMNamespace(ns, "nls");
//指定调用的方法
OMElement method = fac.createOMElement("getGreeting", omNs);
//为方法添加值
OMElement value = fac.createOMElement("name", omNs);
value.addChild(fac.createOMText(value, "world"));//value.setText("world");
method.addChild(value);
method.build();
System.out.println(method);
/******************************************************/

OMElement result = client.sendReceive(method);
System.out.println(result.getFirstElement().getText());
}
如果出现下面这种错误,那么应该是你的options没有与targetEPR关联起来,即少了这一句:options.setTo(targetEPR);

Exception in thread "main" org.apache.axis2.AxisFault: Address information does not exist in the Endpoint Reference (EPR).The system cannot infer the transport mechanism.

RPC 是远程方法的调用。尽管WebService是基于XML的但是你仍然可以使用远程方法调用这种模式来进行WebService的实现,尤其是在那种简单的请求相应的模型中。在这个过程中,传输中的XML文件所描述的更多是有关远程方法的信息。

Document方式,与RPC相比较在XML文件中不是做远程方法的映射,而是一份完整的自包含的业务文档,当Service端收到这份文档后,先进行 预处理(比如词汇的翻译和映射),然后再构造出返回消息。这个构造返回消息的过程中,往往不再是简简单单的一个方法调用,而是多个对象协同完成一个事务的 处理,再将结果返回。

这两种方式的区别:对于第一种方法提供了很多自动化的工具使得远程方法的调用能够很容易的完成,而后一种方法缺少一系列工具的支持,需要开发者手工完成。

推荐使用Document方式。由于它在以下方面具有RPC所不具备的优点。

使用Document方式,你可以充分利用XML的功能去描述和验证一份业务文档,而在RPC模型中XML仅仅被用于描述方法的信息。

使用Document方式,在客户的Service的提供者之间不再需要紧密的约定,而RPC模型需要客户和Service的提供者紧密相连,一旦方法发生变化,客户端就需要做相应的改动。这不符合低耦合系统的要求,而在文档交换方式中则灵活的多。

由于业务数据是自包含的,显然文档模型更利于采用异步处理。

3. 使用wsdl2java.bat自动生成代码

wsdl2java.bat在axis2-1.6.2\bin目录下

首先设置AXIS2_HOME环境变量(当然不设置也可以,不过为了操作方便,还是设置一下),在cmd窗口下切换到工程根目录下,运行命令:

%AXIS2_HOME%\bin\wsdl2java -uri http://localhost:8080/axis2/services/SimpleService?wsdl -p test -s

在运行这个命令时,安装了两个java(一个32位,一个64位)的人可能会遇到说JAVA_HOME没有正确设置的错误:

The JAVA_HOME environment variable is not defined correctly

This environment variable is needed to run this program

NB: JAVA_HOME should point to a JDK/JRE

可以用编辑器打开wsdl2java.bat,在最前面加上这一句

set JAVA_HOME=C:\Program Files (x86)\Java\jdk1.7.0(当然,要根据你自己的java安装目录来修改,写上其中一个jdk的安装目录即可)

其中-uri指定了wsdl文件的路径,可以是本地路径也可以是网络路径;-p指定了生成的java类的包名;-s表示只生成同步调用的代码(相应的,有-a选项表示只生成异步调用的代码,如果两个都不指定,那么两种代码都会生成)

还有比较有用的参数是-o,可以指定你想要生成的java类所在的目录(结果java文件的路径将会是<-o指定的目录>/src/<-p指定的包名>)

其他的一些参数可以通过%AXIS2_HOME%\bin\wsdl2java直接看到

wsdl2java.bat命令生成的Stub类将WebService方法的参数都封装在了相应的类中,类名为方法名,例如,getGreeting方法的参数都封装在了GetGreeting类中,要想调用getGreeting方法,必须先创建GetGreeting类的对象实例。下面是调用的代码:

public static void stubClient() throws Exception{
SimpleServiceStub stub = new SimpleServiceStub();
SimpleServiceStub.GetGreeting gg = new SimpleServiceStub.GetGreeting();
SimpleServiceStub.GetNum nn = new SimpleServiceStub.GetNum();
gg.setName("stub");
System.out.println( stub.getGreeting(gg).get_return());
System.out.println(stub.getNum(nn).get_return());
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: