Web服务和SOA(一) 上

翻译自<<Service Oriented Architecture with Java>>(使用Java开发面向服务的架构)一书之第二章

 

本章我们将详细讲述SOA的实现,并开始我们的Web服务实践之旅。在本章中,我们将会看到,为什么在企业交互的环境中,XML是消息交换的正确选择。接下来我们开始定义一个示例的Web服务,采用自顶向下的方法来开发我们第一个Web服务。然后我们再采用颇为通用的两种传输协议改进我们的程序。

通过对Web服务两种风格(RPCDocument)的比较,我们可以看到采用Document风格的Web服务更加完善,并被广泛使用。在本章的最后,我们将简单介绍一下最流行的几种Web服务实现框架。

 

SOA的实施方法

 

实施SOA的第一步其实很简单,即:确定您的应用所包含的业务功能。下面我们就仔细分析这句话的含义:

(1)     确定:就是要找到软件组成的独立模块,这些模块是自包含的,并且从功能上说,它们是不可分割的(具有功能上的原子性)。这就要求我们在设计时,要把您的问题域按照软件调用规范切分成良好定义的模块,同时也要确定这些模块的边界。对业务模块调用者而言,他们要按照契约式软件规范来正确调用这些模块。在软件设计时,请牢记一条,在多个环境(项目)中都能使用的一个模块就是软件开发中的金块。从某种意义上说,确定出软件中的业务功能,就是一种更高层次的抽象,它将我们以前对“接口”的抽象提高到业务层面上。

 

(2)     业务功能:这个词是指在SOA实践中,我们将专注于业务层(MVC概念中的M),而不是表示层和控制层(MVC模式中的VC)。我们在这里只讨论服务,而良好设计的服务应该和表示层相互独立,服务对表现它们的表示层一无所知。

 

(3)     应用所包含的:应用程序可能包含许多软件层,但我们这里的应用程序强调的是多个而非仅仅一个应用程序。这是SOA实施方法的一个“大跃进”,它超越了我们现在正在进行的项目,我们只需做少量的工作,就可以让SOA中的业务组件超越单一项目,它们可以非常容易地使用在以后的应用程序中。

现在,假定我们按照上面的设计方法设计出了我们所需的服务,下一步我们该做什么呢,我们又如何实现它们呢?

我们不妨先举一个服务的例子,这个例子将返回所有的客户列表,它不需要输入参数,并返回一串对象列表。

服务的消费者(例如用户界面)如何能调用到该服务,并得到它所请求的对象列表呢?这可以通过多种方式实现,下面是其中最为流行的几种:

(1)     使用本地调用:就Java而言,本地调用可以通过RMI(远程方法调用)SocketsServletsJMS来实现;

(2)     使用分布式对象交换中间层:例如服务消费者可使用CORBADCOM来调用服务;

(3)     使用基于文本的交换协议来调用服务:服务消费者可以发送基于文本流的请求,然后可获得包含数据的应答文本。这是Web服务实现的基础。

 

第一种方法非常直接,当它有一些缺陷,它必须依赖于一种语言,服务及其消费者都必须使用同一种语言,比如Java.Net等,并且,服务及其消费者交换对象的版本还必须相同;否则,对象传输就会失败。

分布式对象传输在相当长的时间内非常成功,尤其是CORBA的跨平台特性为后来的可互操作性提供了奠定了良好的基础。

 

第三种基于文本交换的实现方法表明,在客户端和服务器端都需要进行序列化和反序列化操作。但客户端发送请求时,需要将对象序列化成文本格式,然后发送;但服务器收到请求后,它需要将文本经过序列化转换成对象。同样的过程也发送在服务应答的流程中。序列化和反序列化貌似增加了对象交换的复杂性,其实不然,请想想这样做的优势:软件能完全独立于技术,实现了软件之间的松散耦合。

将数据嵌入到文本中最自然的方法莫过于通过XML来实现。

 

XML的优点和不足

 

XML语言由W3C1998年为了数据交换的目的而设计的。对着时间的推移,该语言的魅力也开始显现。XML的主要优点有以下四个方面:

                具有结构化特性
               
是可移动的
               
具可扩展性
               
具文本格式

 

XML的不足

 

以树型结构组织的XML语言优势可能有一些缺点。例如,XML在表示共享的对象应用方面有些不足,所以人们通常争论,XML是否是表示一个任意对象的最佳选择。想想我们前面举的例子,假设您在伦敦有许多客户,使用XML表示这些客户列表时,就会产生数据冗余。这是因为在客户这个XML实体中,其城市属性值都相同。这是人们所不能接受的。其实,这个例子恰恰反证了人们对于XML的误用。在上例中,城市这个属性应该算作一个实体而非属性。这个问题的更好的解决方法是,向关系数据库学习,把重复的数据搬移到主要对象之外,在主要对象中只应用这些重复对象的ID号即可。

客户端可以使用有状态方法(Stateful Approach),首先得到城市这个实体的列表。当它调用getAllCustomers服务时,服务器返回的客户列表的城市属性只需ID即可,而不需完整的城市名,返回的示例客户列表如清单1所示:

程序清单1—有状态方法(Stateful Approach)

 

 

<Customers>

<customer>

          <id>4</id>

<name>Smith Ltd</name>

<location>

<address>39, Kensington Rd.</address>
<city>LND</city>

</location>

</customer>

<customer>

          <id>7</id>

<name> Merkx & Co.</name>

<location>

<address>39, Venice Blvd.</address>
<city>LAX</city>

</location>

</customer> <id>7</id>

...

</Customers>

 

而且,我们还可以采用无状态方法(Stateless Approach),实现自包含的服务,即在我们的XML应答中,嵌入所需要的所有数据对象。示例代码如清单2所示:

程序清单2—无状态方法(Stateless Approach)

<Entireresponse>

<cities>

<city>

<id>LND</id>

<name>London</name>

<country>UK</country>

</city>

<city>

<id>LAX</id>

<name>Los Angeles</name>

<country>USA</country>

</city>

</cities>

<customers>

<customer>

<id>4</id>

...

<location>

...

<city>LND</city>

</location>

</customer>

<customer>

<id>7</id>

...

<location>

...
<city>LAX</city>

</location>

</customer>

...

</customers>

</Entireresponse>

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值