如何实现支持REST的Java Business Services?

日期: 2011-03-23 作者:Vedesh Dambal 来源:TechTarget中国 英文

  REpresentational State Transfer (REST)是一种架构原则,其中将web服务视为资源,可以由其URL唯一标识。RESTful Web服务的关键特点是明确使用 HTTP 方法来表示不同的操作的调用。

  REST的基本设计原则对典型CRUD操作使用HTTP协议方法:

  •   POST-创建资源
  •   GET-检索资源
  •   PUT–更新资源
  •   DELETE-删除资源

  REST服务的主要优势在于:

  它们是跨平台(Java、.net、PHP 等)高度可重用的,因为它们都依赖基本HTTP协议。

  它们使用基本的XML,而不是复杂的SOAP XML,使用非常方便。

  基于REST的web服务日益成为后端企业服务集成的首选方法。与基于SOAP的web服务相比,它的编程模型简单,而本机XML(而不是SOAP )的使用减少了序列化和反序列化过程的复杂性,并且不再需要其他作用相同的第三方库。

  当前用于构建RESTful服务,比如Apache CXF、RESTlet、JAX-WS API和REST支持的基于Java的框架可从Spring 3.0中获得,它在开发和 XML 配置方面非常复杂,通常需要长期的学习。此外,由于这些框架依赖特定版本的jar文件,它们很难跨应用程序服务器环境集成。另外,由于一些同时支持SOAP和REST服务的尝试(Apache CXF、JAX-WS),它们软件包也往往很大,也可能会影响性能。

  因此本文建议使用更简单的可扩展框架将业务服务公开为类REST服务。该框架是轻量级的,采用标准的Front Controller(前端控制器)模式,非常便于理解。它也是可扩展的,可以通过API或任何其他集成模式(如ESB)集成后端服务。通过使用自定义XML序列化程序、JAXB或任何其他对象到XML转换工具,可以方便地配置数据交换模型。

  本文将详细描述此框架。

  架构概述

  在J2EE应用程序中,Java API或服务公开为 Stateless Session Bean API(Session Fa?ade 模式)或SOAP web服务。在这些服务与使用非 Java技术 (如.net或PHP)的客户端应用程序集成时,处理SOAP Web服务将变得非常麻烦,还涉及到大量的开发工作。

  这里提到的方法通常用于有很多服务、服务可以重复使用,但使用SOAP创建快速集成障碍的互操作性和开发成本很大的组织,帮助它们进行服务集成。此外,在内部治理组织不会在企业ESB或EAI上公开服务的情况下,很难以点到点的方式集成两种不同的技术服务。

  例如,在电信IT环境中:

  将一个SMS发送到特定圆的SMSC,公开为SOAP web服务或EJB API;或在CRM应用程序中创建服务请求,使用MQ或JMS绑定通过ESB公开为一个数据库存储的过程 (如 Oracle CRM);或者 创建Sales Order(销售订单)请求,用于使用SMSGateway的移动SMS的Distributor。如果以上服务是由一个非 Java 应用程序使用的,那么使用SOAP web服务的集成会很麻烦,并需要更多的开发工作。

  这种新方法可以用一种框架的形式实现,使它可以在Java服务公开为一种类REST的资源的其他领域中重新使用。这种方法类似于Struts框架方法,由以下组件组成(如下图所示):

图 1. 架构概述

图 1. 架构概述

  该架构包括Front Controller,作为接收请求并向客户端提供响应的中心点。Front Controller将请求处理委托给包含此框架处理逻辑的 ActionController。ActionController执行验证,将请求映射到相应的Action,并调用生成响应的动作。为请求处理、日志记录和异常处理这些可以被单个Action以及ActionController使用的动作提供了各种Helper Service。

  框架组件

  下图展示了框架的各个组件以及彼此之间如何相互关联。

图 2. 框架组件

图 2. 框架组件

  各种组件描述如下:

  服务客户端

  这是一个需要调用服务的客户端应用程序。此组件可以是基于Java的,也可以是任何其他客户端,只要它能够支持HTTP方法

  通用组件

  这些都是日志记录、 异常处理和任何常见功能所需的实用程序服务或者实现所需的常量。在示例代码中使用Apache Commons日志记录和 Log4j 实现。

  RESTServiceServlet

  框架使用Front Controller模式进行集中请求处理,并使用此Java Servlet组件处理输入的请求。它支持常见的HTTP方法,如GET、PUT、POST和DELETE。

  RESTActionController

  此组件是核心框架控制器,管理加载服务和框架配置的核心功能,验证请求,映射请求与配置REST动作并执行动作。

  RESTConfiguration

  该组件负责在运行时加载和缓存框架配置,以及各种REST服务配置。此组件供RESTActionController用于确定请求要调用的正确动作,并验证输入请求。

  RESTMapping

  此组件存储在配置文件中指定的REST动作映射。映射主要包括客户端调用的URI和进行处理的动作类。

  ActionContext

  此组件封装执行REST动作所需的所有功能。它可以帮助开发人员提供请求和响应处理功能,因此开发人员只需要编写实际的业务逻辑实现代码。它向动作组件隐藏协议特定的请求和响应对象,因此允许独立测试POJO之类。它还提供一个指向XML Binding Service的句柄,让Java业务对象可以基于配置的XML Binding API方便地转换为XML,反之亦然。RESTActionController动态配置此组件,并将其提供给Action组件。

  XMLBinding

  此组件封装Java XML Binding机制,提供了一个统一的界面用于将Java业务对象转换为XML,反之亦然。通过实现标准的框架接口,它支持任何XML绑定机制,如JAXB、SDO、Castor等。默认情况下,它为 XMLEncoder 和 XMLDecoder 提供了开箱即用功能。

  Configuration XML

  此组件包含框架和服务配置。当开发REST服务时,它们可以加入服务配置文件中。框架配置包含日志记录和XML Binding服务,不需要定期更换。

  处理典型POST请求的这些组件之间的交互如下所示:

图 3. 组件交互

图 3. 组件交互

  如上图所示,REST服务配置最初加载,并缓存到RESTConfiguration组件中。对于REST服务的每个HTTP请求,RESTServiceServlet组件将请求委托到RESTActionController,它又会检索相应的映射、验证请求、创建ActionContext组件以及路径和查询输入,并调用Action类 (例如,createUserAction)。Action类调用后端Java业务服务进行处理。

  让所有组件运作起来

  本节介绍了这篇文章提供的框架的示例实现。它展示了类关系图、各种配置文件和显示如何将上述设计付诸实行的代码片段。

  注意: 示例代码可能没有遵循所有Java编码的最佳做法,因为它只是一个示例。

  示例实现

  下图显示了示例实现中的类。蓝色所示的类是框架外部的类,将它们放在这里是为了展示与框架的结构关系。

图 4. 类图

图 4. 类图

  配置文件

  配置文件 “rest-services-config.xml” 包含 REST 服务表示形式和相应的Java Action之间的映射,如下:

  清单 1. REST 服务配置
    

以下是引用片段:
<?xml version=”1.0″ ?>
<rest-config>
  <rest-api id=”CreateUserProfile” uri=”/Registration/CreateUser” method=”POST”>
     <handler id=”RegAction” class=”ws.registration.restactions.CreateProfile”/>
  </rest-api>
  <rest-api id=”GetUserProfile” uri=”/Registration/GetUser” method=”GET”>
     <handler id=”RegAction” class=” ws.registration.restactions.GetProfile”/>
  </rest-api>

</rest-config>

  在该示例实现中,XML Binding服务实现在”rl-config.xml”文件中配置的框架配置文件如下所示。通过修改此文件实现的任何自定义实现都可以接入,只要实现了XMLBindingService接口。

  清单 2:框架配置
    

以下是引用片段:
# XML Binding Implementation Service
# Default implementation
ws.rest.xmlbinding.service.impl=ws.rest.xmlbinding.service.impl.XMLEncDecServiceImpl

  日志配置文件 “ws_log.properties” 指定log4j属性和日志文件的位置。这可以按需要作出适当修改。

  Controller Servlet

  RESTServiceServlet在web.xml中配置,处理所有具有上下文路径的请求,其中上下文路径的<web-app>/restservices/*如下所示:

  清单 3:Servlet配置
    

以下是引用片段:
<servlet>
    <description></description>
    <display-name>RESTServletService</display-name>
    <servlet-name>RESTServletService</servlet-name>
    <servlet-class>ws.rest.servlet.RESTServiceServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>RESTServletService</servlet-name>
    <url-pattern>/restservices/*</url-pattern>
  </servlet-mapping> 

  REST Action

  对于每个REST资源,例如 GetUserProfile,都将创建一个实现ActionInterface的相应动作类。该接口定义了动作类需要实现的 “doExecute(ActionContext ctx)” 方法。ActionContext提供服务,获取 REST 路径输入或查询参数,获取XMLBindingService实例并将XML输出发送到客户端,不公开Action的协议细节。PathInputs是一个包含路径值的List对象,路径值的顺序与它们在URL中指定的顺序相同。

  清单 4:Action代码片段
    

以下是引用片段:
public class GetProfile implements ActionInterface {
 
  public void doExecute(ActionContext context) throws Exception {
   // Get the value from URL path
   String userName = context.getPathInputs().get(0);
   // Invoke backend service to retrieve user profile
   UserProfileBean bean = getUser(userName);
   
   
   // Serialize the bean using framework service and send response
   String xml = context.getXMLBindingService().serialize(bean);
   // Use the ActionContext to generate XML and 
   context.sendResponse(response, xml);
}

  动作类负责使用超类中的XMLBindingService以XML形式生成输出。请查看示例实现的ws.registration.restactions.GetProfile类。ActionContext还可以提供协议特定的HttpServletRequest和HttpServletResponse对象,以防需要自定义处理。它还提供了Path值和URL参数。

  XML Binding

  该代码示例提供了一个Java XML Binding的实现,该实现使用java.beans.XMLEncoder和java.beans.XMLDecoder类。XML Binding服务实现接受一个JavaBean对象,并将其转换为上述Encoder和Decoder相应的XML表示形式。如果需要JAXB实现,那么可以开发一个实现 ws.rest.xmlbinding.service.XMLBindingService接口的实现类。

  执行示例服务

  示例代码分发包含示例WAR文件”RESTWS.war”,它可以部署在Tomcat容器中(已在Apache Tomcat版本6.0.20上进行了测试)。JDK要求是JDK 1.5以上。

  成功部署该应用程序之后,在浏览器中输入以下URL:http://localhost:8080/RESTWS/html/CreateProfile.html ,如下所示:

图 5. 创建Profile Service输入

图 5. 创建Profile Service输入

  该页面调用REST服务

  POST <url-prefix>/Registration/CreateProfile

  您可以修改在 <string></string> 标记中指定的XML值。

  注意:请注意XML结构依赖于JavaBean对象和Java使用的XML序列化技术。

  提交时,动作类显示成功消息,表示后端服务的调用。可以查看 ws_log.log 文件调试消息。

图 6. 创建Profile Service输出 

图 6. 创建Profile Service输出

  类似地,实现示例GET <url-prefix>/Registration/GetProfile/{username}服务以检索配置文件,如下图所示:

图 7. 执行Profile Service

图 7. 执行Profile Service 

  小结

  因此,使用这一框架,我们认为我们可以轻松地将任何Java服务公开为一种REST API。通过使用XML作为输出数据,服务可以方便地集成以任何非Java语言编写的客户端应用程序,只要它支持HTTP协议。此外,实现Action类大大减少了开发工作。

  可以开展进一步工作,使用适当的异常处理和缓存服务加强实现。也可以实现注释支持,协助开发人员创建默认配置,无需在配置文件中指定它。

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

相关推荐

  • SAP收购CallidusCloud 与Salesforce竞争

    一直被称为后台办公巨头的SAP现在似乎也想在前台办公大展拳脚。 最新的迹象是SAP收购CallidusClou […]

  • API开发与管理大作战

    2014将会是API管理方法新旧PK的一年,据Delyn Simons说,她领导了Mashery开发者的外展团队。应用编程接口(API)的主流化和私有化在新的一年也将掀起波澜,她在波士顿“Future Insights Ultimate Developer Event 2013”大会上预测说。

  • 公共API外包管理是否值得考虑?

    公共API外包管理是指聘请一个专家小组来解决可扩展性问题,同时也提出几套可替代的方案。

  • API设计如龙生九子 各不相同

    IT咨询管理公司CA Technologies对API产业做了个问卷调查,问卷内容涉及API设计风格以及管理部署的新动向。调查结果表明,JSON与XML可谓两分天下。