编写基于JAX-RPC的客户端
既然所有概念和逻辑上的背景知识都讲清楚了,现在就可以为一个真正的Web服务创建客户端了。
Web服务和客户端的所有代码都可以在文件RegisterClient.zip中找到。也可以找到一个主机版本的Web服务RegisterPerson.jws。要将该示例安装到WebLogic Workshop中,需要将文件解压缩到BEA_HOME/weblogic700/samples/workshop/applications/samples/proxy目录中。关于该示例的使用说明,请参考readme.html文件。
我将用于这个演示的Web服务叫做RegisterPerson.jws,它接收一个叫做Person的记录。该记录中包含两个联系(地址)记录,一个家庭的和一个工作的。Web服务的其他操作允许查询或者更改当前的家庭或工作联系信息,或者允许查询整个Person记录。Person记录包含两个其他记录这一事实告诉你如何处理一个Web服务接口中的复杂数据类型。另外,RegisterPerson.jws是会话的。setPerson方法启动一个会话,除endSession之外的所有其他方法继续这个会话。endSession用来结束这个会话。本文稍后会解释Web服务会话的概念。
JAX-RPC客户端都遵循同一个样式。一旦创建了一些客户端并熟悉了它们的样式,只要看一下Web服务的文档(例如,WebLogic Workshop Web服务的测试视图)就可以猜出Web服务的JAX-RPC接口了。如果没有Web服务文档的话,可以通过检查那些生成客户端JAR文件的Java文件来找出接口。下面的部分描述了基本的JAX-RPC模式。
例示优异代理类
你的客户端第一个例示的是一个名为_Impl的优异类。优异代理类名称的开始部分应该是Web服务的名称。例如,对于RegisterPerson.jws来说,该优异代理类的名称就是RegisterPerson_Impl.。
在示例客户端RegisterClient.java中,优异代理类是在第225行例示的。
m_proxyImpl = new RegisterPerson_Impl(
"http://localhost:7001/samples/proxy/register/RegisterPerson.jws?WSDL");
优异代理类的构造器参数是URL或者Web服务WSDL文件的文件系统路径。如果在Web服务URL的末端加进一个"?WSDL",那么按照Web服务工具(WebLogic Workshop,.NET,Apache)上的约定,Web服务将返回它的WSDL文件。(你可能会问,"如果Web服务不可用怎么办?",那还用说,你的Web服务客户端就不能正常工作了呗,难道不是吗?)使用URL form是个好办法,因为这允许JAX-RPC客户端代码按照Web服务的当前WSDL来验证自己。如果指定了WSDL文件的本地副本,并且由于你获得了副本Web服务也更改了它的接口,那么Web服务客户端就可能出现故障,但原因不明。通过指定WSDL的URL,可以立即发现你的客户端代码是否过时。
获得一个协议类代理对象
JAX-RPC包括了每个协议的协议类代理类,这些协议可以被Web服务理解(特别是对于WSDL文件中定义的各个端口类型)。代理类都被起了个名字。在示例Web服务中,只支持SOAP协议,所以代理类被称为RegisterPersonSoap。在优异代理类中通过调用一个accessor方法,就可以得到协议类代理类。所以在我们的例子中,RegisterPerson_Impl定义了方法getRegisterPersonSoap,该方法返回一个RegisterPersonSoap代理类的例子。
In RegisterClient.java, this happens on line 235:
在RegisterClient.java中,这出现在第235行。
m_proxy = m_proxyImpl.getRegisterPersonSoap();
调用协议类代理对象上的方法
协议类代理类,我们的例子中是RegisterPersonSoap,定义了精确反映Web服务操作的stub方法。通常,proxy方法被称为stub方法,因为它们实际上并没有做真正的方法应该做的事情,而是调用远程方法来完成真正的任务。由于示例Web服务定义了一个setPerson方法,所以SOAP类代理类也定义了一个setPerson stub方法。为了调用Web服务的setPerson方法,首先应该调用代理的setPerson stub方法。
记住这个看似简单的方法调用实际上为你做了不少事情。它将方法的所有参数编组,以组成一个适当地格式化过的SOAP消息(意味着它将参数从Java类型转换成XML类型),再将这个消息发送给Web服务,然后等待SOAP响应消息,最后解分组响应消息中的数据并把这些数据作为Java类型返回给你。
对RegisterClient.java中setPerson的调用发生在第278行。
m_proxy.setPerson(p, startHeader);
这里,p是一个Person对象,startHeader是一个会话头部(本文后面会解释)。
客户端的Java类路径
RegisterClient.java示例中包含了一个可用来编译客户端的build.xml ant script,以及可分别在Windows和Linux/UNIX机器上执行客户端的run.bat和run.sh文件。可以检查这些文件来查看客户端使用的类路径。简单地说,类路径必须包括:
1.客户端类本身
2.使用clientgen创建的或者通过Java Proxy链接从WebLogic Workshop的测试视图中得到的客户端代理JAR文件
3.通用Web服务客户端支持JAR文件webserviceclient.jar,该文件可以在BEA WebLogic Platform 7.0安装文件下的WL_HOME/server/lib目录中找到,也可以通过Proxy Support Jar链接从WebLogic Workshop测试视图中获得。
在webserviceclient.jar中发现的支持类也可以在weblogic.jar中找到,但是类路径中包含的weblogic.jar在测试时容易混淆。你的客户端应该在那些能够访问目标Web服务主机的主机中工作,不管这些主机是否安装了WebLogic Platform。
这(几乎)就是全部事情了
这样说很有道理。Clientgen产生的客户端JAR文件以及底层的JAX-RPC基础使从Java代码中调用Web服务变得很容易。
"等一会儿",你会说,"Person类是从哪里来的,会话头部又是什么"?不要着急,请继续往下看。
相关文章