Spring学习笔记23

定义Contract

开发contract-firstweb service最重要的就是定义contract,我们需要定义发送给服务和从服务接收的消息,不用考虑服务被实现的方式和消息被处理的方式。

虽然这里主要讨论Spring-WS,但其实这和Spring是无关的。因为定义一个web servicecontract与服务的实现细节是独立的。它只关注于它应该有什么而不是它如何去拥有什么。Web servicecontract-first强调与服务通讯的消息。所以,定义contract首先就要确定这些消息的格式。我们将创建一段样本XML消息来定义servicecontract

创建样本XML消息

       前面的扑克牌服务以五张扑克牌作为输入,产生一个扑克牌名字作为输出。为服务编写一个样吧输入消息的XML代码如下:

<EvaluateHandRequest

xmlns="http://www.springinaction.com/poker/schemas">

    <card>

       <suit>HEARTS</suit>

       <face>TEN</face>

    </card>

    <card>

       <suit>SPARES</suit>

       <face>KING</face>

    </card>

    <card>

       <suit>HEARTS</suit>

       <face>KING</face>

    </card>

    <card>

       <suit>DIAMONDS</suit>

       <face>TEN</face>

    </card>

    <card>

       <suit>CLUBS</suit>

       <face>TEN</face>

    </card>

</EvaluateHandRequest>

这段XML很直观,总共有5<card>元素,每一个都有一个<suite><face>。这很好地描述了这个扑克牌服务。所有的<card>元素都封装在<EvaluateHandRequest>元素中——这就是我们要发送给service的消息。

       与输入消息类似,输出消息如下:

<EvaluateHandResponse

    xmlns="http://www.springinaction.com/poker/schemas">

    <handName>Full House</handName>

</EvaluateHandResponse>

EvaluateHandResponse消息只包含了一个handName元素,handName保存了输出信息。这些样本消息就是contract的基础。现在我们已经完成了最困难的部分。

创建数据contract

       现在我们开始创建服务contract。在此之前,我们先把contract从概念上划分几个概念:

·data contract:定义与服务通讯的消息。在本例中,这包括EvaluateHandRequestEvaluateHandResponse消息的schema定义。

·operational contract:定义服务执行的操作。值得注意的是,一个SOAP操作并不需要关联于服务API中的一个方法。

       一般地,这两个contract部分都被定义在一个单个的WSDL文件中。WSDL文件通常都包含一个内嵌的XML Schema,该Schema定义了data contract。另外,WSDL文件定义了operational contract,在<wsdl:binding>元素中包含一个或多个<wsdl:operation>元素。

       data contract是被定义在XML Schema(XSD)中的,XSD允许我们准确地定义一个消息。我们不但可以定义消息中的元素,还可以指定消息类型和为消息设置限定条件。

       有很多XSD inference工具可供使用,例如TrangTrangXML作为输入产生一个XSD文件作为输出。Trang是基于Java实现的,所以可以应用于任何JVM上。Trang可以产生RELAX NG(一种schema风格)schema,也可以产生XSD文件。对于Spring-WS来说,我们可以使用Trang来产生XSD,执行下面的命令即可得到xsd文件:

java –jar trang.jar request.xml response.xml PokerTypes.xsd

Trang将会产生一个名为PokerTypes.xsd的文件,但XSD并不是完美的。因为Trang可以产生XSD,所以Trang对于XML中的数据类型做了一些假设。大多数情况下这些假设没有问题,但是有时候我们还是需要对产生的XSD进行修改调整。

       例如,Trang假设<suit><face>元素的值应该被定义为noncolonized name(xsNCName)。一个noncolonized name不带有命名空间的前缀。我们实际想要的元素只是一个简单的字符串(xsstring)。所以,我们需要把<suit><face>定义为string类型:

<xs:element name=”suit” type=”xs:string” />

<xs:element name=”face” type=”xs:string” />

我们还知道对于<suit>元素只有4个可能的值,所以我们加上限定条件:

<xs:element name="suit" type="schemas:Suit" />

<xs:simpleType name="Suit">

    <xsd:restriction base="xs:string">

       <xsd:enumeration value="SPADES" />

       <xsd:enumeration value="CLUBS" />

       <xsd:enumeration value="HEARTS" />

       <xsd:enumeration value="DIAMONDS" />

    </xsd:restriction>

</xs:simpleType>

同样地,<face>元素只有13个合法值,这里就不再一一列出其定义了。另外值得注意地是,Trang错误地假定<EvaluateHandRequest>包含一个未限制的<card>元素(maxOccurs=”unbounded”),但是对于本例来说它包含5张卡片。因此,我们需要调整它的定义为:

<xs:element name="EvaluateHandRequest">

    <xs:complexType>

      <xs:sequence>

        <xs:element minOccurs="5" maxOccurs="5" ref="schemas:card"/>

      </xs:sequence>

    </xs:complexType>

  </xs:element>

<EvaluateHandResponse>来说,Trang生成的代码还可以,我们当然也可以为其加上限定值,但这不是必须得。

       现在我们已经有了poker hand服务的data contract,但operational contract呢?我们需要WSDL的帮忙。毕竟,WSDL是定义web service的标准。我们当然可以手工编写WSDL,但是这太容易,没有多大乐趣。

       首先要做的就是创建一个服务的端点(endpoint)contract只定义了服务通讯的消息,没有定义它们是如何被处理的。下面来看在Spring-WS中如何创建消息的endpoint,以及Spring-WS如何处理来自服务客户端的消息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值