用 JAX-RPC 发送与接收 SOAP 消息(4)
 
- UID
- 1066743
|

用 JAX-RPC 发送与接收 SOAP 消息(4)
JAX-RPC SEI 客户机应用程序接下来的一层抽象需要更多的设置工作,但是最终客户机的代码可就简单得多了。您可以从 WSDL 开始入手。JAX-RPC 实现提供了将 WSDL转换成 Java 的代码生成器,它除了别的东西之外,还可以生成服务端点接口(Service Endpoint Interface,SEI)。这是客户端访问Web 服务应用程序的 Java 接口。清单 6 中显示了 XMethods Barnes & Noble 应用程序的一个 SEI。
清单 6. Barnes & Noble SEI1
2
3
4
| package xmethods.bn;
public interface BNQuotePortType extends java.rmi.Remote {
public float getPrice(java.lang.String isbn)
throws java.rmi.RemoteException;
|
在我所使用的 WSDL 转换成 Java 的工具中,我将 http://www.xmethods.net/sd/BNQuoteService.wsdl 的 targetNamespace 映射为 Java 包 xmethods.bn ,这样SEI 就创建在这个包中。SEI 的名字派生于 WSDL 的 portType 名称: BNQuotePortType 。 getPrice 方法派生于 portType 的 getPrice 操作以及它所引用的消息及其类型。如果您运行的是自己喜欢的WSDL 转换成 Java 的工具,您将看到 xmethods.bn 包中还生成了其他的类。您必须将这些类一起编译,但是您的客户机应用程序只需要知道SEI。
为了用这个 SEI 来调用 Web 服务,您必须完成下面三个与 DII 相同的步骤:
- 用WSDL实例化一个 Service 类
- 实例化一个代理
- 调用代理的操作
SEI 和 DII 的第 1步是类似的。第 2步和第 3步则大大简化,尤其是第 2步。
用 WSDL 实例化一个 ServiceSEI 模型和 DII 模型在这一步的唯一区别就是,在 SEI 中您需要多提供一些信息,即 WSDL。
清单 7. 为 SEI 实例化一个 Service 类 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.rpc.Service;
import javax.xml.rpc.ServiceFactory;
public class SEITip {
public static void main(String args[]) {
try {
// Create a service class with WSDL information.
QName serviceName = new QName(
"http://www.xmethods.net/sd/BNQuoteService.wsdl",
"BNQuoteService");
URL wsdlLocation = new URL
("http://www.xmethods.net/sd/2001/BNQuoteService.wsdl");
ServiceFactory factory = ServiceFactory.newInstance();
Service service = factory.createService(
wsdlLocation,
serviceName);
}
catch (Throwable t) {
t.printStackTrace();
}
}
|
实例化一个代理一旦您获得了这个服务,就必须找到这个 SEI 的一个实现。这个实现就是用来访问真正应用程序的代理。所有有关如何访问那个应用程序的信息都隐藏在这个实现中,而这些信息是从WSDL 的服务端口中搜集的,因此只要您获得了这个代理,您就不需要进行任何设置了;所有的工作都已经替您做好了。
清单 8. 实例化 SEI 的一个实现1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.rpc.Service;
import javax.xml.rpc.ServiceFactory;
import xmethods.bn.BNQuotePortType;
public class SEITip {
public static void main(String args[]) {
try {
// Create a service class with WSDL information.
QName serviceName = new QName(
"http://www.xmethods.net/sd/BNQuoteService.wsdl",
"BNQuoteService");
URL wsdlLocation = new URL
("http://www.xmethods.net/sd/2001/BNQuoteService.wsdl");
ServiceFactory factory = ServiceFactory.newInstance();
Service service = factory.createService(
wsdlLocation,
serviceName);
// Get an implementation for the SEI for the given port
QName portName = new QName("", "BNQuotePort");
BNQuotePortType quote = (BNQuotePortType) service.getPort(
portName,
BNQuotePortType.class);
}
catch (Throwable t) {
t.printStackTrace();
}
}
|
调用代理的操作最后,对操作的调用过程可能不太简单:
清单 9. 调用 SEI 上的一个操作1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.rpc.Service;
import javax.xml.rpc.ServiceFactory;
import xmethods.bn.BNQuotePortType;
public class SEITip {
public static void main(String args[]) {
try {
// Create a service class with WSDL information.
QName serviceName = new QName(
"http://www.xmethods.net/sd/BNQuoteService.wsdl",
"BNQuoteService");
URL wsdlLocation = new URL
("http://www.xmethods.net/sd/2001/BNQuoteService.wsdl");
ServiceFactory factory = ServiceFactory.newInstance();
Service service = factory.createService(
wsdlLocation,
serviceName);
// Get an implementation for the SEI for the given port
QName portName = new QName("", "BNQuotePort");
BNQuotePortType quote = (BNQuotePortType) service.getPort(
portName,
BNQuotePortType.class);
// Invoke the operation
float price = quote.getPrice("0672324229");
System.out.println("price = " + price);
}
catch (Throwable t) {
t.printStackTrace();
}
}
|
|
|
|
|
|
|