使用 Struts 2 开发 RESTful 服务

转载 使用 Struts 2 开发 RESTful 服务 

作者:李 刚, 自由撰稿人

原文地址:http://www.ibm.com/developerworks/cn/java/j-lo-struts2rest/

2009 年 8 月 28 日

      从 V2.1 开始,Struts 2 开始提供 Convention 插件,它允许根据“约定”来搜索 Action,以及管理 Action 和 Result 的映射。另外,Struts 2.1 还提供了 REST 插件,使 Struts 2 可以支持 Rails 风格的 URL,以对外提供 REST 风格的资源服务。本文作者通过代码示例演示了这些特性。
REST 简介

        REST 是英文 Representational State Transfer 的缩写,这个术语由 Roy Thomas Fielding 博士在他的论文《Architectural Styles and the Design of Network-based Software Architectures》中提出。从这篇论文的标题可以看出:REST 是一种基于网络的软件架构风格。

提示:国内很多网络资料将 REST 翻译为“表述性状态转移”,不过笔者对这个翻译不太认同。因为这个专业术语无法传达 REST 的含义,读者可以先不要理会 REST 到底该如何翻译,尽量先去理解 REST 是什么?有什么用?然后再来看这个术语的翻译。关于 Roy Thomas Fielding 博士的原文参见如下地址:http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm。

       REST 架构是针对传统 Web 应用提出的一种改进,是一种新型的分布式软件设计架构。对于异构系统如何进行整合的问题,目前主流做法都集中在使用 SOAP、WSDL 和 WS-* 规范的 Web Services。而 REST 架构实际上也是解决异构系统整合问题的一种新思路。

      如果开发者在开发过程中能坚持 REST 原则,将可以得到一个使用了优质 Web 架构的系统,从而为系统提供更好的可伸缩性,并降低开发难度。关于 REST 架构的主要原则如下:

     网络上的所有事物都可被抽象为资源(Resource)。
     每个资源都有一个唯一的资源标识符(Resource Identifier)。
     同一资源具有多种表现形式。
     使用标准方法操作资源。
     通过缓存来提高性能。
     对资源的各种操作不会改变资源标识符。
     所有的操作都是无状态的(Stateless)。
     仅从上面几条原则来看 REST 架构,其实依然比较难以理解,下面笔者将从如下二个方面来介绍 REST。

      资源和标识符 

      现在的 Web 应用上包含了大量信息,但这些信息都被隐藏在 HTML、CSS 和 JavaScript 代码中,对于普通浏览者而言,他们进入这个系统时无法知道该系统包含哪些页面;对于一个需要访问该系统资源的第三方系统而言,同样无法明白这个系统包含多少功能和信息。

URI 和 URL

与 URI 相关的概念还有 URL,URL 是 Uniform Resource Locator,也就是统一资源定位符的意思。其中 http://www.crazyit.org 就是一个统一资源定位符,URL 是 URI 的子集。简而言之:每个 URL 都是 URI,但不是每个 URI 都是 URL。


从 REST 架构的角度来看,该系统里包含的所有功能和信息,都可被称为资源(Resource),REST 架构中的资源包含静态页面、JSP 和 Servlet 等,该应用暴露在网络上的所有功能和信息都可被称为资源。

除此之外,REST 架构规范了应用资源的命名方式,REST 规定对应用资源使用统一的命名方式:REST 系统中的资源必须统一命名和规划,REST 系统由使用 URI(Uniform Resource Identifier,即统一资源标识符)命名的资源组成。由于 REST 对资源使用了基于 URI 的统一命名,因此这些信息就自然地暴露出来了,从而避免 “信息地窖”的不良后果。

对于当今最常见的网络应用来说,资源标识符就是 URI,资源的使用者则根据 URI 来操作应用资源。当 URI 发生改变时,表明客户机所使用的资源发生了改变。

从资源的角度来看,当客户机操作不同的资源时,资源所在的 Web 页(将 Web 页当成虚拟的状态机来看)的状态就会发生改变、迁移(Transfer),这就是 REST 术语中 ST(State Tranfer)的由来了。

客户机为了操作不同状态的资源,则需要发送一些 Representational 的数据,这些数据包含必要的交互数据,以及描述这些数据的元数据。这就是 REST 术语中 RE(Representational)的由来了。理解了这个层次之后,至于 REST 如何翻译、或是否真正给它一个中文术语,读者可自行决定。

操作资源的方式

对于 REST 架构的服务器端而言,它提供的是资源,但同一资源具有多种表现形式(可通过在 HTTP Content-type 头中包含关于数据类型的元数据)。如果客户程序完全支持 HTTP 应用协议,并能正确处理 REST 架构的标准数据格式,那么它就可以与世界上任意一个 REST 风格的用户交互。这种情况不仅适用于从服务器端到客户端的数据,反之亦然——倘若从客户端传来的数据符合 REST 架构的标准数据格式,那么服务器端也可以正确处理数据,而不去关心客户端的类型。

典型情况下,REST 风格的资源能以 XHTML、XML 和 JSON 三种形式存在,其中 XML 格式的数据是 WebServices 技术的数据交换格式,而 JSON 则是另一种轻量级的数据交换格式;至于 XHTML 格式则主要由浏览器负责呈现。当服务器为所有资源提供多种表现形式之后,这些资源不仅可以被标准 Web 浏览器所使用,还可以由 JavaScript 通过 Ajax 技术调用,或者以 RPC(Remote Procedure Call)风格调用,从而变成 REST 风格的 WebServices。

REST 架构除了规定服务器提供资源的方式之外,还推荐客户端使用 HTTP 作为 Generic Connector Interface(也就是通用连接器接口),而 HTTP 则把对一个 URI 的操作限制在了 4 个之内:GET、POST、PUT 和 DELETE。通过使用通用连接器接口对资源进行操作的好处是保证系统提供的服务都是高度解耦的,从而简化了系统开发,改善了系统的交互性和可重用性。

REST 架构要求客户端的所有的操作在本质上是无状态的,即从客户到服务器的每个 Request 都必须包含理解该 Request 的所有必需信息。这种无状态性的规范提供了如下几点好处:

无状态性使得客户端和服务器端不必保存对方的详细信息,服务器只需要处理当前 Request,而不必了解前面 Request 的历史。
无状态性减少了服务器从局部错误中恢复的任务量,可以非常方便地实现 Fail Over 技术,从而很容易地将服务器组件部署在集群内。
无状态性使得服务器端不必在多个 Request 中保存状态,从而可以更容易地释放资源。
无状态性无需服务组件保存 Request 状态,因此可让服务器充分利用 Pool 技术来提高稳定性和性能。
当然,无状态性会使得服务器不再保存 Request 的状态数据,因此需要在一系列 Request 中发送重复数据,从而提高了系统的通信成本。为了改善无状态性带来的性能下降,REST 架构填加了缓存约束。缓存约束允许隐式或显式地标记一个 Response 中的数据,这样就赋予了客户端

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值