技术开发 频道

基于Spring HTTP Invoker的两全其美的远程服务

    【IT168 专稿】使用Spring HTTP invoker从普通Java类中实现远程服务可以把HTTP通讯的简单性和Java内置的对象序列化机制结合起来。

    远程是企业分布式计算中的一项基本组成部分。你从同一台服务器里(Java虚拟机)调用的服务或者类称之为远程服务,但是如果你需要和一个外部程序(在不同的服务器上或者不同的组织里)通讯的话,它就必须实现为远程服务。Spring框架提供了一种独特且灵活的方式来把商业类实现为远程服务。

    Spring远程体系结构的核心是服务对象,它们是POJO,也被称为Spring bean。Spring框架把这些服务对象和它们是如何成为远程服务的等基础设施细节隔相分离,这样开发人员就可以集中精力在服务对象的商业接口上,而不是陷入这些细节的纠缠中。

    这种远程模型提供了商业服务的远程抽象。它处理编组的和未编组的方法参数,也处理服务方法里抛出的任何异常,用未验证的RemoteAccessException把它们封装起来。为了实现多种类型的服务,Spring使用了几种设计模式。例如,它使用代理设计模式来把你的调用翻译为指向输出服务的URL的HTTP POST请求。

    这篇文章解释了如何使用Spring来实现远程服务。它演示了使用Spring远程API把旧的普通Java对象(POJO)转换为能够让外部程序调用它的商业函数的远程服务。演示使用了一个处理贷款的应用程序的例子来把一个商业服务实现为一个远程HTTP服务,并且从一个测试客户端请求类里的商业方法。

一、Spring 远程方式是如何工作的呢?

    让我们来仔细看一下Spring远程机制是如何工作的。它提供了如下的元素把一个Java类实现为一个远程服务:

1. Remote Service Exporters – 这些类用来创建被客户端程序调用的远程服务端点。 Service exporters也管理查找远程服务的任何注册。
2. Proxy Factory Beans – 这些是工厂类,用来创建客户端使用的连接到远程服务的代理。
3. HTTP Invoker – 正如前面所述,Spring HTTP invoker使用了一种远程模型,你可以使用它通过HTTP进行远程调用,同时使用Java序列化技术传递Java对象。它使得由一个普通Java类实现远程服务容易了很多,并且让你把精力集中在远程服务的商业接口上而不是远程基础设施的细节上。它依靠基础设施RMI invoker,但是使用HTTP做为传输协议。
在客户端方面,Spring HTTPinvoker提供两种类型的客户端:由Java SE提供的标准API和普通HttpClient API。缺省使用HttpClient。

先让我们看一下Spring在所有远程技术列表中所支持的远程技术:

•  基于接口的设计: 基于接口的设计使得客户端不必知道远程服务的实现细节。在客户端代码中不做任何修改,实现方式就可以改变。
•  测试驱动的开发: 应用程序中所有组件在容器之外都应该是可测的。例子中将会使用JUnit写简单的单元测试,来验证你写的代码中每个类设计的合理性。
•  层次化的体系结构: 层次化的体系结构提供了松散的耦合,独立性和灵活性。一个典型的J2EE应用程序都有这样的层次:用户接口(UI),应用(或者控制器),域(域模型或服务),和基础设施。例子中的应用程序有控制器,服务和域这几层。
•  概念分离: 既然远程函数和商业服务无关,概念的分离在服务的实现上发挥着重要作用。
•  轻量级服务: 例子使用Spring HTTP invoker API来实现远程服务。 和其他组件模型相比HTTP invoker还是相当轻量的。
•  非侵入性: Spring因为在商业应用中有非侵入的API而成为出色的框架。它使用Aspects和AOP等技术,反向控制(IoC),代理和工厂模式等设计模式,你可以封装服务类中商业任务的实现细节,只把接口留给客户端。
除了这些目标,例子在应用类的设计和编码上还遵循敏捷软件开发方式:

 

二、商业需求

    既然你已经知道了应用的设计目标,那么让我们来讨论一下实际的商业需求。样例应用程序是一个贷款处理系统,客户使用它为家庭抵押贷款提交应用。远程例子所使用的商业用例是来处理特定家庭财产的洪灾鉴定检查。 洪灾鉴定检查对于每个家庭贷款应用都是必不可少的,以确保财产不在洪灾区。如果它位于洪灾区,户主需要支付一种”813费用”(813是用来区别洪灾鉴定费用的代码)来得到洪灾保险。
洪水地图指的是高,中,低级别”洪灾危险区”的区域,最高危险等级的区域称为”特殊洪灾危险区”。在高洪灾危险区(AE,A,或者AO地区)的财产,任何一年都有1%的几率发生洪灾,并且在30年的抵押期中会有26%的几率发生洪灾。在VE或者V地区(也是高险)的不动产在任何一年都有1%的几率发生洪灾,还面临着沿海暴风雨的危险。在等级或中等洪灾危险区(B或C区)的家庭在高险区之外,那里洪灾危险系数有所减少但并没有消除。
洪灾鉴定检查一旦借用人完成了家庭贷款应用且为贷款数量选择了利率以后就会被触发。洪灾鉴定检查需要在贷款处理之前,这样抵押处理的签名承受阶段才能开始。

三、用例

这是在洪灾鉴定检查用例中所用到的步骤:
1. 客户完成贷款应用,输入细节信息如借用人姓名,财产名称,财产地址,城市,邮编,和贷款数额。
2. 用户选择一个贷款产品和利率并把贷款锁定为一段特定时间(例如30天或者45天)。
3. 贷款应用程序调用基于财产细节比如地址和邮编的洪灾鉴定检查。
4. 基于客户的财产所在邮编,如果指定的财产在洪灾区并且如果它需要洪灾鉴定,洪灾鉴定服务就确定下来(这种调用是同步的,所以客户端在继续贷款应用处理之前将要等待服务的反馈)。
5. 一旦洪灾检查请求返回,贷款就被提交给一个自动承受系统(AUS)来获得借用人的信用历史和贷款应用的风险评估。

四、技术设计
按照敏捷开发过程,下一步是为定义的需求进行技术设计。例子使用下面的设计(类和方法)来完成用例中的需求。
1. 客户类(FloodCertClient)调用洪水控制器类(FloodCertController)中的requestFloodCheck()方法。
2. 控制器然后通过在HTTP请求中发送贷款细节调用服务(FloodCertService)中的processFloodCheck()方法。
3. 洪灾服务调用FloodDAO类来访问后端数据库,检查指定财产是否需要洪灾鉴定。
4. DAO返回一个带有洪灾鉴定结果的结果对象,它被传到客户端在Web页面上显示。
由于远程服务是一个企业商业域模型的入口点,服务层做为一个整体来设计也是非常重要的下面是一些你在设计远程服务时要牢记在心的需要考虑的地方:
1. 远程调用类型(远程调用应该是无状态的还是有状态的?)
2. 远程调用引用类型(调用是同步的还是异步的?)
3. 客户端类型(Java,。NET,或是一些其他类型的客户端)
4. 操作系统(Windows,Unix,或者另一操作系统)
5. 事务(你是否需要远程服务成为事务类型的,这样任何数据库或者JMS队列在服务方法中的更新都会做为一个工作单元被提交或者回滚。)
为了实现用例所有的需求,贷款处理应用的例子将使用下面的技术和框架:
• Tomcat 5。5
• Spring 2。0
• JUnit
• Commons HttpClient
• Eclipse
• Ant

五、实现

HTTP invoker远程例子使用两个配置XML文件来为你写的实现洪灾远程服务的类定义Spring beans: loanapp-servlet。xml和loanapp-client。xml。

下面是用HTTP invoker为贷款处理应用例子实现远程服务的步骤:

1. 创建一个HTTP invoker服务输出者类(HttpInvokerServiceExporter)
2. 创建一个HTTP代理(使用HttpInvokerProxyFactoryBean)。你要细化这个类里的参数像serviceUrl和serviceInterface。
3. 为客户端调用远程HTTP服务定义一个URL映射。
4. 在loanapp-servlet。xml文件里配置Spring beans。
5. 在web。xml文件里配置Spring Web层(DispatcherServlet)。
6. 写客户类(使用HTTP或者Commons HttpClient)。
7. 写一个JUnit测试用例来调用客户类中的方法。

六、测试

下载的源代码包括一个JUnit测试客户端(FloodCertClientTest),用来测试调用洪灾远程服务的客户类。它根据财产的不同邮编来调用具有不同测试贷款应用的客户端。基于提交的财产邮编,洪灾服务返回洪灾鉴定分析的结果。

七、两全其美的远程技术

Spring远程技术为把商业域服务实现为远程服务提供了一种简单灵活的解决方案。它也提供了多种协议下(当然在不同的URL)同一服务的灵活机制。例如,你可以把样例应用程序中的洪灾鉴别检查服务实现为一个RMI服务(Java客户端利用较快的Java-to-Java远程),也可以是非Java客户端的HTTP服务。这样,你只需在一个地方写商业服务逻辑,但是却把服务实现为两种远程服务端点。

HTTP invoker框架以普通Java服务接口和持续使用和配置风格来实现Java类作为远程服务提供了必要的代理。这种解决方案展示了把HTTP通讯的简单性和Java内置的对象序列化结合起来的两全其美的远程解决方案。这使得HTTP invoker成为替代RMI或者Hessian/Burlap的一种很好的选择。

HTTP invoker的一个明显的局限性在于它只在Spring框架中提供。这意味着不管是客户端还是服务应用端都必须用Spring来实现。但是当你需要一个轻量,容易建立,并且灵活的远程解决方案时它就成为非常好的选择。

0
相关文章