input发送a.jax_设计和开发JAX-WS 2.0 Web服务

在你开始前

关于本教程

在本教程中,您将设计一个开发订单处理应用程序,该应用程序将其功能公开为Web服务,由此各种使用者可以以与平台无关的方式下达订单信息。

目标

在学习完本教程之后,您可以应用概念和知识来使用JAX-WS技术为您的应用程序开发Web服务。

先决条件

为了成功完成本教程,您应该对Web服务技术有基本的了解,并且对Java编程有所了解。

系统要求

要运行本教程中的示例,您需要安装Java平台标准版(Java SE)6.0。

JAX-WS简介

为什么选择JAX-WS?

JAX-WS是一项旨在简化Java中Web服务和Web服务客户端的构造的技术。 它提供了完整的Web服务堆栈,可简化开发和部署Web服务的任务。 JAX-WS支持WS-I Basic Profile 1.1,这确保了使用JAX-WS堆栈开发的Web服务可以由遵循WS-I Basic Profile标准的任何编程语言开发的任何客户端使用。 JAX-WS还包括用于XML绑定的Java体系结构(JAXB)和带有Java附件API的SOAP(SAAJ)。

JAXB通过提供将XML模式映射到Java代码中的表示形式的便捷方法来启用数据绑定功能。 JAXB不需要将XML消息中的XML模式消息转换为Java代码,而无需完全了解XML和SOAP解析。 JAXB规范定义了Java和XML模式之间的绑定。 SAAJ提供了一种处理SOAP消息中包含的XML附件的标准方法。

此外,JAX-WS通过提供注释库将普通的旧Java对象(PO​​JO)类转换为Web服务来加快Web服务的开发。 它还指定了从Web服务描述语言(WSDL)中定义的服务到实现该服务的Java类的详细映射。 遵循JAXB规范定义的映射,将WSDL中定义的任何复杂类型映射为Java类。 JAX-WS以前与Java平台企业版(Java EE)5捆绑在一起。JAX-WS2.0规范是根据Java Community Process(JCP)的JSR 224开发的。

开发网络服务

合同优先方法与代码优先方法

入门JAX-WS的一个好方法是首先开发一个Web服务。 您可以使用以下两种方法之一开发Web服务:

  • 首先签约:从WSDL签约开始,并生成Java类以实现服务。
  • 代码优先:从Java类开始,并使用批注生成WSDL文件和Java接口。

合同优先的WSDL方法要求对WSDL和XSD(XML架构定义)进行很好的理解,以定义消息格式。 如果您是Web服务的新手,那么从代码优先方法开始是个好主意,本教程将在本教程中使用它来开发Web服务。

代码优先的Web服务开发

使用代码优先方法,您可以从一个Java类开始,这些类实现要作为服务公开的功能。 当Java实现已经可用并且您需要将实现公开为服务时,代码优先方法特别有用。

开发订单处理Web服务

首先,我们创建一个订单处理Web服务,该服务接受订单信息,运输信息和订购的商品,并最终生成一个确认ID作为响应。 清单1中提供了订单处理服务的代码。这是一个虚拟实现,可在控制台上打印客户ID和商品数量,然后返回虚拟订单ID A1234 。 (您可以在本文的“ 下载”部分中下载完整应用程序的源代码。)将源代码提取到C驱动器中,在该驱动器中创建了一个名为JAXWS-Tutorial的文件夹。 该文件夹包含源代码,如清单1所示。

清单1.订单处理Web服务实现
package com.ibm.jaxws.tutorial.service;

import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import com.ibm.jaxws.tutorial.service.bean.OrderBean;


//JWS annotation that specifies that the portType name of the 
//Web service is "OrderProcessPort," the service name 
//is "OrderProcess," and the targetNamespace used in the generated
//WSDL is "http://jawxs.ibm.tutorial/jaxws/orderprocess."

@WebService(serviceName = "OrderProcess",
		portName = "OrderProcessPort",	
		targetNamespace = "http://jawxs.ibm.tutorial/jaxws/orderprocess")
	
//JWS annotation that specifies the mapping of the service onto the
// SOAP message protocol. In particular, it specifies that the SOAP messages 
//are document literal.

@SOAPBinding(style=SOAPBinding.Style.DOCUMENT,use=SOAPBinding.Use.LITERAL,
			parameterStyle=SOAPBinding.ParameterStyle.WRAPPED)

public class OrderProcessService {

	@WebMethod
	public OrderBean processOrder(OrderBean orderBean) {

		// Do processing...
		System.out.println("processOrder called for customer"
				+ orderBean.getCustomer().getCustomerId());

		// Items ordered are
		if (orderBean.getOrderItems() != null) {
			System.out.println("Number of items is "
					+ orderBean.getOrderItems().length);
		}

		//Process order.

		//Set the order ID.
		orderBean.setOrderId("A1234");

		return orderBean;
	}
}

OrderBean包含清单2中所示的订单信息。具体地说,它包含对客户,订单项和送货地址对象的引用。

清单2.保存订单信息的OrderBean类
package com.ibm.jaxws.tutorial.service.bean;

public class OrderBean {

	private Customer customer;

	private Address shippingAddress;

	private OrderItem[] orderItems;

	private String orderId;

	public Customer getCustomer() {
		return customer;
	}

	public void setCustomer(Customer customer) {
		this.customer = customer;
	}

	public String getOrderId() {
		return orderId;
	}

	public void setOrderId(String orderId) {
		this.orderId = orderId;
	}

	public Address getShippingAddress() {
		return shippingAddress;
	}

	public void setShippingAddress(Address shippingAddress) {
		this.shippingAddress = shippingAddress;
	}

	public OrderItem[] getOrderItems() {
		return orderItems;
	}

	public void setOrderItems(OrderItem[] orderItems) {
		this.orderItems = orderItems;
	}

}

开发JAX-WS Web服务的起点是带有javax.jws.WebService批注的Java类。 所使用的JAX-WS注释是Java平台规范(JSR-181)的Web服务元数据的一部分。 您可能已经注意到, OrderProcessService带有WebService批注,该批注将类定义为Web服务终结点。

OrderProcessService类(带有@javax.jws.WebService批注的类)隐式定义了服务端点接口(SEI),该接口声明了客户端可以在服务上调用的方法。 该类中定义的所有公共方法,除非该方法使用@WebMethod批注注释,并且exclude元素设置为true ,否则将映射到WSDL操作。 @WebMethod批注是可选的,用于自定义Web服务操作。 除了exclude元素之外, javax.jws.WebMethod批注还提供了操作名称和操作元素,用于自定义操作的名称属性和WSDL文档中的SOAP操作元素。 这些属性是可选的。 如果未定义,则默认值从类名称派生。

实施Web服务后,您需要生成部署服务所需的任何工件,然后将Web服务打包为已部署的工件(通常作为WAR文件),并将WAR文件部署到支持JAX-WS的任何兼容服务器上2.0规范。 生成的典型工件是提供将Java对象转换为XML以及基于服务接口的WSDL文件和XSD模式的类。

为了进行测试,Java 6捆绑了一个轻量级Web服务器,可以通过调用简单的API调用将Web服务发布到该服务器。 接下来,您将了解如何使用这种方法测试Web服务。

发布服务

生成JAX-WS工件

通过运行wsgen工具,可以为订单处理Web服务生成JAX-WS可移植工件。 该工具读取Web SEI类,并生成Web服务部署和调用所需的所有工件。 wsgen工具为需要发布的Web服务生成WSDL文件和XSD模式。

为了生成JAX-WS工件,首先需要编译服务和​​bean源:

  1. 打开命令提示符,然后导航到c:\ JAXWS-Tutorial。
  2. 运行以下命令来编译Java文件并将类文件放入其各自的文件夹中:

    javac com\ibm\jaxws\tutorial\service\*.java com\ibm\jaxws\tutorial\service\bean\*.java
  3. 运行以下命令以生成JAX-WS工件:

    wsgen -cp . com.ibm.jaxws.tutorial.service.OrderProcessService -wsdl

wsgen工具提供了许多选项,例如通过提供-wsdl选项为服务生成WSDL和模式构件。 运行此命令后,您应该看到JAXWS-Tutorial文件夹中生成的OrderProcess.wsdl和OrderProcess_schema1.xsd,以及在com \ ibm \ jaxws \ tutorial \ service \ jaxws文件夹中创建的JAX-WS构件。

生成工件后,您可以通过运行以下Web服务发布者客户端来发布订单处理Web服务。

  1. 通过从c:\ JAXWS-Tutorial文件夹运行以下命令来编译OrderWebServicePublisher

    javac com\ibm\jaxws\tutorial\service\publish\OrderWebServicePublisher.java
  2. 然后运行以下命令:

    java com.ibm.jaxws.tutorial.service.publish.OrderWebServicePublisher

运行Java程序后,您应该看到以下消息: The web service is published at http://localhost:8080/OrderProcessWeb/orderprocess. To stop running the web service, terminate this Java process. The web service is published at http://localhost:8080/OrderProcessWeb/orderprocess. To stop running the web service, terminate this Java process.

这将在http:// localhost:8080 / OrderProcessWeb / orderprocess位置发布订单Web服务。 您可以通过显示订单处理Web服务生成的WSDL来验证Web服务是否正在运行:

  1. 打开浏览器,然后导航到http:// localhost:8080 / OrderProcessWeb / orderprocess?wsdl。

分析OrderWebServicePublisher

在分析WSDL和架构工件之前,让我们分析OrderWebServicePublisher的代码。 清单3提供了OrderWebServicePublisher客户端的源代码。

清单3.发布订单处理Web服务的代码
package com.ibm.jaxws.tutorial.service.publish;

import javax.xml.ws.Endpoint;

import com.ibm.jaxws.tutorial.service.OrderProcessService;

public class OrderWebServicePublisher {

	public static void main(String[] args) {

		Endpoint.publish("http://localhost:8080/OrderProcessWeb/orderprocess",
				new OrderProcessService());

	}

}

Endpoint.publish()方法提供了一种方便的方法来发布和测试JAX-WS Web服务。 publish()具有两个参数:Web服务的位置和JAX-WS Web服务实现类。 publish()方法在指定的URL(在本例中为本地主机和端口8080)创建一个轻量级的Web服务器,并将Web服务部署到该位置。 轻量级Web服务器在Java虚拟机(JVM)中运行,可以通过有条件地调用endpoint.stop()方法或终止OrderWebServicePublisher客户端来终止。

分析生成的WSDL

要查看生成的订单处理Web服务WSDL,请在浏览器中键入以下URL位置: http://localhost:8080/OrderProcessWeb/orderprocess?wsdl

让我们分析一些重要的WSDL方面,并从分析生成的XSD开始,看看如何基于JAX-WS元数据生成WSDL和模式构件。 使用xsd:import标记将其导入到WSDL文件中(参见清单4)。 schemaLocation指定XSD的位置。

清单4.包含订单处理模式定义的WSDL文件
<types>
	
    <xsd:schema>
      <xsd:import namespace="http://jawxs.ibm.tutorial/jaxws/orderprocess" 
	  schemaLocation="OrderProcess_schema1.xsd"/>
    </xsd:schema>
</types>

schemaLocation (http:// localhost:8080 / OrderProcessWeb / orderprocess?xsd = 1)放在浏览器中,以查看在浏览器中呈现的架构定义。 让我们分析一下这里发生的情况:模式定义以targetNamspacetns声明开头,该声明映射到您在OrderProcessService@WebService批注中定义的targetNamespace http://jawxs.ibm.tutorial/jaxws/orderprocess。 清单5提供了代码。

清单5.模式名称空间声明
<xs:schema version="1.0" 
    targetNamespace="http://jawxs.ibm.tutorial/jaxws/orderprocess"
    xmlns:tns="http://jawxs.ibm.tutorial/jaxws/orderprocess" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema">

较早执行的wsgen工具生成两个包装bean类, ProcessOrderProcessOrderResponse ,它们保存订单处理Web服务的输入和输出消息。 基于包装器bean类,将生成以下模式元素:

  • processOrder的类型为processOrder ,它表示一种复杂类型,其中包含一个名称为arg0且元素为orderBean 。 您可以看到ProcessOrder类和processOrder复杂类型之间的一对一映射。
  • processOrderResponseprocessOrderResponse类型类似,其定义映射到ProcessOrderResponse类。

让我们更仔细地查看清单6中的内容。

清单6. processOrder的模式声明
<xs:element name="processOrder" type="tns:processOrder"/>
  <xs:element name="processOrderResponse" type="tns:processOrderResponse"/>
  <xs:complexType name="processOrder">
    <xs:sequence>
      <xs:element name="arg0" type="tns:orderBean" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>

清单7中所示的orderBean类型定义映射到OrderBean类。 orderBean类型定义包括:

  • 一个类型为customer customer元素。
  • 一个类型为stringorderId
  • orderItems (这是一个数组,因为它指定的maxOccurs属性作为unbounded ),其类型为orderItem
  • 类型为address shippingAddress
清单7. processOrder的模式声明
<xs:complexType name="orderBean">
<xs:sequence>
<xs:element name="customer" type="tns:customer" minOccurs="0" /> 
          <xs:element name="orderId" type="xs:string" minOccurs="0" /> 
          <xs:element nillable="true" maxOccurs="unbounded" name="orderItems" 
                          type="tns:orderItem" minOccurs="0" /> 
          <xs:element name="shippingAddress" type="tns:address"   
                         minOccurs="0" /> 
</xs:sequence>
</xs:complexType

类似地, customerorderItemsaddress的其余模式定义分别映射到CustomerOrderItemAddress Java Bean。

分析了模式定义之后,让我们重新访问WSDL中的消息定义,如清单8所示processOrder指定消息processOrderprocessOrderResponse ,它们的组成部分是processOrderprocessOrderResponse (您已经了解了它们的模式定义)。 portType指定操作processOrder其输入消息为processOrder ,其输出消息为processOrderResponse

清单8. WSDL文档中的processOrder消息元素
<message name="processOrder">
  		<part element="tns:processOrder" name="parameters" /> 
  </message>
  <message name="processOrderResponse">
  		<part element="tns:processOrderResponse" name="parameters" /> 
  </message>
  <portType name="OrderProcessService">
  <operation name="processOrder">
  <input message="tns:processOrder" /> 
  <output message="tns:processOrderResponse" /> 
  </operation>
  </portType>

接下来,定义WSDL绑定。 这将soap:binding样式定义为documentsoap:body使用tag作为literal作为操作processOrder输入和输出消息格式。 生成的WSDL定义映射到您在OrderProcessService类上定义的@SOAPBinding注释(请参见清单9)。

清单9. WSDL文档的绑定信息
<binding name="OrderProcessPortBinding" type="tns:OrderProcessService">
  <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> 
 <operation name="processOrder">
  <soap:operation soapAction="" /> 
 <input>
  <soap:body use="literal" /> 
  </input>
  <output>
  <soap:body use="literal" /> 
  </output>
  </operation>
</binding>

接下来,定义WSDL服务。 这些指定端口和相应的绑定类型,以及服务的实际位置。 这通常是一个HTTP位置,在这种情况下为http:// localhost:8080 / OrderProcessWeb / orderprocess。 您可以在清单10中详细看到这一点。

清单10. WSDL文档的服务信息
<service name="OrderProcess">
  <port name="OrderProcessPort" binding="tns:OrderProcessPortBinding">
  <soap:address location="http://localhost:8080/OrderProcessWeb/orderprocess" /> 
</port>

这样,您就分析了生成的WSDL和模式构件。 清单11展示了Web服务客户端调用processOrder操作时发送的示例SOAP请求消息。

清单11.用于processOrder操作的示例SOAP消息
<?xml version="1.0"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:ns1=" http://jawxs.ibm.tutorial/jaxws/orderprocess" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soapenv:Body>
<ns1:processOrder>
<arg0>
<customer><customerId>A123</customerId>
<firstName>John</firstName><lastName>Smith</lastName></customer>
<orderItems><itemId>11</itemId><qty>11</qty></orderItems>
</arg0>
</ns1:processOrder>
</soapenv:Body>
</soapenv:Envelope>

创建Web服务客户端

从WSDL创建Web服务客户端

在本部分中,您将学习如何从WSDL创建Web服务客户端。 JAX-WS带有一个称为wsimport的工具,该工具用于从WSDL生成JAX-WS便携式工件。 通常生成的可移植工件包括以下内容:

  • 精工
  • 服务(您需要实现的服务实现类)
  • 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命令。但是,在执行此操作之前,请确保已按照步骤5所述运行OrderWebServicePublisher来发布Web服务。在生成JAX-WS工件部分中

清单12. wsimport命令,用于生成Web服务客户端使用的JAX-WS工件
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类( AddressCustomerOrderBeanOrderItem ):通过读取OrderProcessService WSDL中定义的模式定义生成
  • RequestWrapperResponseWrapper类( ProcessOrderProcessOrderResponse ):将输入和输出包装为文档文字包装样式
  • 服务类( OrderProcess ):您的客户端用于向Web服务发出请求的类
  • 服务接口( OrderProcessService ):类包含您的服务实现的接口

现在看一下如何使用上面生成的构件来创建Web服务客户端。 com \ ibm \ jaxws \ tutorial \ service \ client文件夹中提供了示例参考代码。 清单13提供了Web服务客户端的代码。

清单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");
      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()来检索该服务的代理(也称为端口getOrderProcessPort() 。 端口实现服务定义的服务接口。
  • 调用端口的processOrder方法,并传递在OrderBean的第二个列表项中创建的OrderBean实例。
  • 从服务获取OrderBean响应并打印订单ID。

运行Web服务客户端

要运行Web服务客户端,请首先通过运行JAXWS-Tutorial文件夹中的以下命令来编译Web服务客户端:

javac com\ibm\jaxws\tutorial\service\client\OrderClient.java

通过使用以下命令提供定单处理Web服务的WSDL URL,执行Web服务客户端:

java com.ibm.jaxws.tutorial.service.client.OrderClient http://localhost:8080/OrderProcessWeb/orderprocess?wsdl

当执行Web服务客户端时,您将在运行OrderWebServicePublisher的控制台上看到以下输出:

processOrder called for customer A123
Number of items is 1

在执行Web服务客户端的控制台上,您将获得以下输出:

Order id is A1234

正如在客户端代码中看到的那样,您不会处理用于调用Web服务操作的任何基于SOAP或XML的格式。 取而代之的是,您处理生成的用于输入和输出消息的JAXB类,并使用服务接口和服务类对象,它们充当Web服务调用的存根。 存根负责根据JAXB批注创建SOAP请求,并将SOAP响应转换回Java对象。

您现在已经成功创建并发布了Web服务,并通过Web服务客户端执行了该服务!

摘要

在本教程中,您学习了如何使用代码优先的开发方法和JAX-WS技术来设计和开发Web服务。 JAX-WS是一个不错的选择,因为它提供了完整的Web服务堆栈,以简化Web服务的开发和部署。

您在本教程中开发的订单处理Web服务使用文档样式的Web服务,该服务可确保服务使用者和服务提供者使用XML文档进行通信。 XML文档遵守定义良好的合同,通常使用XML Schema定义创建合同。 XML模式格式指定服务使用者可以调用的业务消息的合同,并遵守该合同。 文档样式的Web服务应该是开发企业Web服务的首选方法。


翻译自: https://www.ibm.com/developerworks/webservices/tutorials/ws-jax/ws-jax.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值