从 WSDL 创建 Web 服务客户机
在本部分,我们将了解如何从 WSDL 创建 Web 服务客户机。JAX-WS 提供了名为 wsimport 的工具,用于从 WSDL 生成 JAX-WS 可移植构件。生成的可移植构件通常包括以下内容:
* SEI
* 服务(需要实现的服务实现类)
* 从模式类型生成的 JAXB 生成类
* 从 wsdl:fault 映射的
异常类(如果有)
客户机使用生成的构件调用 Web 服务。Web 服务客户机并不需要处理任何 SOAP 格式(如创建或
解析 SOAP 消息)。这将由 JAX-WS 运行时予以处理,此运行时将使用生成的构件代码(JAXB 生成类)。Web 服务将处理 Java 代码(JAXB 生成类),从而减少了开发 Web 服务客户机和对 Web 服务调用操作的工作。
先使用 wsimport 工具从 OrderProcess WSDL 生成 JAX-WS 构件。然后要创建 Web 服务客户机,后者使用生成的构件代码调用订单处理 Web 服务。要生成 JAX-WS 构件,贤进入到 JAXWS-Tutorial 目录,并运行清单 12 中所示的 wsimport 命令。不过,进行操作前,请确保已经按照生成 JAX-WS 构件部分中的步骤 5 所述的方法,通过运行 OrderWeb
ServicePublisher 发布了 Web 服务。
清单 12. 用于生成供 Web 服务客户机使用的 JAX-WS 构件的 wsimport 命令
wsimport -keep -p com.ibm.jaxws.tutorial.service.client
http://localhost:8080/OrderProcessWeb/orderprocess?wsdl
-keep 选项指示保留生成的文件,-p 选项指定需要在其中生成构件的包名称。http://localhost:8080/OrderProcessWeb/orderprocess?wsdl 指定 WSDL 文件的位置。以下构件是从 OrderProcessService WSDL 生成的:
* JAXB 类(Address、Customer, OrderBean 和 OrderItem):通过读取 OrderProcessService WSDL 中定义的模式定义生成
* RequestWrapper 和 ResponseWrapper 类(ProcessOrder 和 ProcessOrderResponse):包装 document literal-wrapped 样式类型的输入和输出
* 服务类 (OrderProcess):客户机用于请求 Web 服务的类
* 服务
接口 (OrderProcessService):包含着用于服务实现接口的类
接下来了解一下如何使用上面生成的构件创建 Web 服务客户机。com\ibm\jaxws\tutorial\service\client 文件夹中提供了一个示例参考代码。Web 服务客户机的代码如清单 13 中所示。
清单 13. 订单处理 Web 服务客户机的代码清单
package com.ibm.jaxws.tutorial.service.client;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
public class OrderClient {
final QName qName = new QName(
"http://jawxs.ibm.tutorial/jaxws/orderprocess", "OrderProcess");
public static void main(String[] args) {
if (args.length != 1) {
System.out
.println("Specify the URL of the OrderProcess Web Service");
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|
|--------
XML error: The previous line is longer than the max of 90 characters ---------|
System.exit(-1);
}
URL url = getWSDLURL(args[0]);
OrderClient client = new OrderClient();
client.processOrder(url);
}
private static URL getWSDLURL(String urlStr) {
URL url = null;
try {
url = new URL(urlStr);
} catch (MalformedURLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
return url;
}
public void processOrder(URL url) {
OrderProcess orderProcessingService = new OrderProcess(url, qName);
System.out.println("Service is" + orderProcessingService);
OrderBean order = populateOrder();
OrderProcessService port = orderProcessingService.getOrderProcessPort();
OrderBean orderResponse = port.processOrder(order);
System.out.println("Order id is " + orderResponse.getOrderId());
}
private OrderBean populateOrder() {
OrderBean order = new OrderBean();
Customer customer = new Customer();
customer.setCustomerId("A123");
customer.setFirstName("John");
customer.setLastName("Smith");
order.setCustomer(customer);
// Populate Order Item.
OrderItem item = new OrderItem();
item.setItemId("11");
item.setQty(11);
order.getOrderItems().add(item);
return order;
}
}
上面列出的 Web 服务客户机代码执行以下任务:
* 通过传入 OrderProcess Web 服务的 WSDL URL 和服务的 QName 创建 OrderProcess 类的实例。
* 创建 OrderBean 的实例,并使用 populateOrder() 方法填充订单信息。
* 对服务调用 getOrderProcessPort(),以检索到服务的代理(也称为端口)。端口实现服务所定义的接口。
* 调用端口的 processOrder 方法,并同时传入在上面的第二个列表项目中创建的 OrderBean 实例。
* 从服务获得 OrderBean 响应并输出订单 ID。