使用 Struts 2 开发 RESTful 服务

Posted 程序文刀刘

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用 Struts 2 开发 RESTful 服务相关的知识,希望对你有一定的参考价值。

REST 简介

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

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 中的数据,这样就赋予了客户端缓存 Response 数据的功能,这样就可以为以后的 Request 共用缓存的数据,部分或全部的消除一些交互,增加了网络的效率。但是用于客户端缓存了信息,也就同时增加了客户端与服务器数据不一致的可能,从而降低了可靠性。

Struts 2 的 REST 支持

约定优于配置

Convention 这个单词的翻译过来就是“约定”的意思。有 Ruby On Rails 开发经验的读者知道 Rails 有一条重要原则:约定优于配置。Rails 开发者只需要按约定开发 ActiveRecord、ActiveController 即可,无需进行配置。很明显,Struts 2 的 Convention 插件借鉴了 Rails 的创意,甚至连插件的名称都借鉴了“约定优于配置”原则。

从 Struts 2.1 开始,Struts 2 改为使用 Convention 插件来支持零配置。Convention 插件彻底地抛弃了配置信息,不仅不需要使用 struts.xml 文件进行配置,甚至不需要使用 Annotation 进行配置。而是由 Struts 2 根据约定来自动配置。

Convention 这个单词的翻译过来就是“约定”的意思。有 Ruby On Rails 开发经验的读者知道 Rails 有一条重要原则:约定优于配置。Rails 开发者只需要按约定开发 ActiveRecord、ActiveController 即可,无需进行配置。很明显,Struts 2 的 Convention 插件借鉴了 Rails 的创意,甚至连插件的名称都借鉴了“约定优于配置”原则。

由于 Struts 2 的 Convention 插件的主要特点是“约定优于配置”,当我们已经习惯了 Struts 2 的基本开发方法之后,如果希望改为使用 Convention 插件也非常容易,我们只要放弃 Stuts 2.1 应用原有的配置文件,改为按 Convention 插件的约定来定义 Action 即可。

以 Convention 插件为基础,Struts 2.1 又新增了 REST 插件,允许 Struts 2 应用对外提供 REST 服务。REST 插件也无需使用 XML 进行配置管理。Struts 2.1 通过 REST 插件完全可以提供让人和机器客户端共同使用的资源,并支持 Ruby On Rails 风格的 URL。

RestActionMapper 简介

从本质上来看,Struts 2 依然是一个 MVC 框架,最初设计 Struts 2 时并没有按 REST 架构进行设计,因此 Struts 2 本质上并不是一个 REST 框架。由于 Struts 2 提供了良好的可扩展性,因此允许通过 REST 插件将其扩展成支持 REST 的框架。REST 插件的核心是 RestActionMapper,它负责将 Rails 风格的 URL 转换为传统请求的 URL。

用 WinRAR 打开 struts2-rest-plugin-2.1.6 文件,看到该文件里包含一个 struts-plugin.xml 文件,该文件中包含如下一行:

(c)2006-2024 SYSTEM All Rights Reserved IT常识