`
vanadiumlin
  • 浏览: 504972 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

使用Restful2ActionMapper让Struts2支持REST风格的URL映射

阅读更多

一、概述

REST是由 Roy Fielding 在他的论文《Architectural Styles and the Design of Network-based Software Architectures》中提出的一个术语。关于REST,请参考:http: //www.redsaga.com/opendoc/REST_cn.pdf
在REST的定义中,一个Web应用总是使用固定的URI向外部世界呈现(或者说暴露)一个资源,并使用不同的HTTP请求方法来处理对资源的CRUD (创建、读取、更新和删除)操作。除了我们所熟知的GET和POST这两种HTTP请求方法,HTTP还有HEAD、PUT、DELETE等请求方法。我 们在Web应用中处理来自客户端的请求时,通常只考虑GET和POST,并使用某种URL映射将URL映射到对资源的某种操作。而REST架构风格则要求 使用HTTP的GET、POST、PUT、DELETE来分别表示资源的读取、创建、更新、删除,而URI保持不变。举例来说, /article/2007/8/a001这个URI表示一篇文章,表示形式为:/article/{year}/{month}/{id},对这个资源 的CRUD操作如下(下面的表示形式中,我省去了http://host/context/namespace这样的前缀):
  读取:GET /article/2007/8/a001
  创建:POST /article/2007/8/a001
  更新:PUT /article/2007/8/a001
  删除:DELETE /article/2007/8/a001
如果我们用传统的struts或webwork的开发方法,我们可能会定义一个ArticleAction,定义好CRUD的method,并使用不同的 URI映射来表示这几种操作,比如,我们可能会使用这样的URI来读取article:/getArticle.action?year= 2007&month=8&id=a001,并使用这样的URI来删除article:/deleteArticle.action? year=2007&month=8&id=a001,或者,把这几种操作用相同形式的URI来表示:/article.action? method=get&year=2007&month=8&id=a001。显然,REST风格的URI表示更友好。
Struts2和Webwork2都带了一个RestfulActionMapper来支持REST风格的URI映射,但是它的功能太弱了,表现形式也很 呆板。Struts2(我使用的是Struts 2.0.9)中还有一个Restful2ActionMapper,可以更好地支持REST风格。
从struts2的官方文档中可以找到关于Restful2ActionMapper的说明: Improved restful action mapper that adds several ReST-style improvements to action mapping, but supports fully-customized URL's via XML.

二、配置和使用

现在,我们配置struts2使它使用Restful2ActionMapper。在Web项目中,修改struts.properties文件(它最终会发布到你的web应用的WEB-INF/classes目录中):

struts.mapper.class=org.apache.struts2.dispatcher.mapper.Restful2ActionMapper
struts.enable.SlashesInActionNames=true

当然,你也可以在struts.xml里进行配置,请参考struts2的相关文档。

  这里有个小建议,许多人在WEB-INF/web.xml里对struts2的配置是让struts2处理所有扩展名为action的url,也就是设置url-pattern为*.action。   我的建议是,不要使用扩展名来作为url-pattern,使用基于路径的匹配形式会更好,我一般是使用“/app/*”作为url-pattern。至于扩展名,我一般是在struts.properties文件中指定:
struts.action.extension=html,xml,json
或者,不要扩展名:
struts.action.extension=
  不过,这些都是题外话。

现在,以上面讲到的article为例,我们定义ArticleAction。按照Restful2ActionMapper的规则,URL与method的对应关系如下:
  GET /article => public String index(); 资源索引;
  GET /article/2007/8/a001 => public String view(); 对应于读取操作;
  POST /article/2007/8/a001 => public String create(); 创建资源;
  PUT /article/2007/8/a001 => public String update(); 更新资源;
  DELETE /article/2007/8/a001 => public String remove(); 删除资源;
  GET /article/2007/8/a001!edit => public String edit(); 请求编辑资源,和REST的四种操作没有对应关系;
  GET /article/new 或 GET /article/!editNew => public String editNew(); 请求编辑新资源,和REST的四种操作没有对应关系。
  后两种方式似乎和REST没什么关系,但为传统的Web应用开发提供了方便。比如edit(),服务器返回一个表单页面。但是,如果我们让应用服务器只返 回xml或json,那么这个edit()是可以不要的,有读取操作就够了。(也许把view方法改为read更贴切点)。
按照这些规则,我们在ArticleAction中定义view()、create()、update()、delete()等method,并在这个action中定义year、month、id的getter/setter方法:

java 代码
 
  1. package app;  
  2.   
  3. public class ArticleAction {  
  4.     private String year, month, id;  
  5.     ...  
  6.     getter/setter methods for year,month,id  
  7.     ...  
  8.     public String view() { ... }  
  9.     public String index() { ... }  
  10.     public String create() { ... }  
  11.     public String update() { ... }  
  12.     public String remove() { ... }  
  13. }  


然后我们需要配置这个action,使它能与形如/article/{year}/{month}/{id}的URL对应起来。我们在相应的struts2的action配置文件中加入如下几行:

xml 代码
 
  1. <action name="article/*/*/*" className="app.ArticleAction">  
  2.     <param name="year">{1}</param>  
  3.     <param name="month">{2}</param>  
  4.     <param name="id">{3}</param>  
  5.     <result name="...." type="json..." />  
  6. </action>  

OK!现在已经可以使用这个action了。当然,这还需要浏览器客户端的支持。当你的客户端以GET来请求/article/2007/8/a001 时,struts2就会调用ArticleAction的view方法,而PUT请求则会对应到update方法,DELETE请求会对应到remove 方法...
但是,如果你的客户端只支持GET和POST怎么办?Restful2ActionMapper的文档中提到:To simulate the HTTP methods PUT and DELETE, since they aren't supported by HTML, the HTTP parameter "__http_method" will be used.对于只支持GET和POST的传统网页,我们可以增加一个"__http_method"参数来模拟PUT和DELETE,比如:POST /article/2007/8/a001&__http_method=DELETE。随着Javascript和Ajax框架的发展,我们已 经可以使用PUT和DELETE等方法。Ajax使用XmlHttpRequest进行操作时,在发送请求之前,可以通过设置RequestType的方 式来完成对请求方法的设定。

三、不足之处

Restful2ActionMapper对REST风格的支持是不完全的。在REST风格中,我们可以使用同一个URI来获取同一个资源的多种表现形 式。在发送HTTP请求时,只要我们在请求头中指定一个Accept参数,那么服务器就可以通过判断该参数来决定返回什么类型的数据。如果Accept为 text/xml,服务器会返回xml格式的数据,如果Accept为text/json,则会返回json格式的数据,但URI是固定的。而 Restful2ActionMapper只是作了URI的映射,并没有考虑返回数据的格式问题。要让struts2支持完全的REST风格,我们不得不 对它进行改造,或者,等待它的改进。
另外,Restful2ActionMapper所定义的URL映射规则也有一个小小的“陷阱”。比如,GET /user/1表示读取id为1的user,但按照Restful2ActionMapper的定义,/user/new会对应到action的 editNew方法,如果这个"new"就是某个用户的id呢?为了避开这个陷阱,我宁愿使用/user/!editNew这种丑陋的形式。事实上,随着 客户端技术的发展,我们完全可以不使用editNew方法而构造输入页面,然后向服务器发送POST来创建资源。同样,edit方法也不是必要的。

四、其它

有个struts2的插件,叫jsonplugin,可以让struts2很方便地支持json输出。而Adobe Spry Framework、YUI-ext、DOJO等都能很好地支持json,并能很好地支持HTTP的各种请求方法。我推荐struts2的用户使用 jsonplugin和Adobe Spry Framework或YUI-ext(或其它UI Framework)。Struts2只输出json格式的结果(最好还能输出xml),而UI和数据装配交给Adobe Spry/YUI-ext等去做。这样的组合会让你更好更方便地使用REST风格。
分享到:
评论
1 楼 不想长大 2008-07-25  
很好,很详细啊.....

相关推荐

    Struts2 chm文档

    目录 1.Struts 2权威指南——第1章 Struts 2概述.doc 2.truts 2权威指南——第2章 Struts 2下的HelloWorld.doc 3.Struts 2权威指南——第3章 Struts...11.改写Restful2ActionMapper让Struts2支持REST风格的URL映射.doc

    Struts2+rest简单实例

    在这个"Struts2+rest简单实例"中,开发者创建了一个小型的示例应用,目的是帮助初学者快速理解如何在Struts2框架中集成RESTful服务。以下是这个实例中可能涉及的关键知识点: 1. **Struts2框架基础**:Struts2的...

    Struts2 Rest方式和非Rest方式共存

    在Struts2中,可以通过配置特定的ActionMapper来支持REST风格的URL映射。`RestActionMapper`是Struts2提供的一个关键组件,它负责将RESTful请求映射到相应的Action上。 首先,让我们了解非REST方式的Struts2工作...

    Struts2 支持REST 代码

    在Struts2中支持REST主要通过使用Struts2的REST插件实现。这个插件允许开发者创建RESTful的URL,以便更好地处理HTTP方法(GET、POST、PUT、DELETE等)并返回JSON或XML等数据格式。以下是一些关于Struts2支持REST的...

    struts2_rest整合完整例子

    Struts2 和 REST 整合是一个常见的Web开发实践,它允许开发者构建RESTful风格的Web服务,从而提高应用的可伸缩性和互操作性。在这个完整的例子中,我们将深入探讨Struts2框架如何与REST原则相结合,以及如何通过提供...

    struts2+rest简单实例

    - **配置URL映射**:在`struts.xml`中配置Action与REST URL的对应关系。 - **测试**:使用curl命令或者前端页面进行接口调用,检查响应是否符合预期。 6. **示例应用**: - 该示例可能包含创建用户、获取用户、...

    RESTful-Struts2-2.3.15_JARs

    3. `struts2-rest-plugin-2.3.15.jar`: REST插件,提供了处理RESTful请求的能力,如将URL映射到Action和方法。 4. `xwork-core-2.3.15.jar`: XWork框架的核心库,是Struts2的基础,提供了Action管理和数据绑定等功能...

    struts2-restDmo,struts2下的rest插件小例子

    而Struts2的REST插件则是为了让开发者能够轻松地在Struts2应用中实现RESTful服务。REST(Representational State Transfer)是一种软件架构风格,常用于设计网络应用程序,特别是Web服务。RESTful服务遵循一组特定的...

    Struts2 Spring3 JPA RESTful

    Struts2、Spring3 和 JPA 是 Java Web 开发中常用的三大框架,它们结合RESTful架构,可以构建高效、灵活的Web应用。这篇概述将深入探讨这三个框架以及RESTful服务的相关知识点。 首先,Struts2 是一个基于MVC...

    Struts2请求转restful所需jar包

    Struts2请求转restful所需jar包 ezmorph-1.0.6.jar json-lib-2.3-jdk15.jar struts2-convention-plugin-2.3.14.jar struts2-rest-plugin-2.3.14.jar xstream-1.4.3.jar

    RestFul整合struts所需包

    Struts 2 依然是一个 MVC 框架,...由于 Struts 2 提供了良好的可扩展性,因此允许通过 REST 插件将其扩展成支持 REST 的框架。REST 插件的核心是 RestActionMapper,它负责将 Rails 风格的 URL 转换为传统请求的 URL。

    struts2 restful Demo

    因為剛入職 公司要求會使用struts2 restful風格,剛開始都沒聽說過restful,然後在網上找了N久的講解或demo,都沒找到,花了一週 在老大的指導下搞出來了,希望可以幫助到想學restful風格的同學們

    strusts2包struts2-rest-showcase-2.1.8.war实现ModelDriven接口项目心得

    在本文中,我们将深入探讨如何使用Struts2的`ModelDriven`接口以及如何控制URL,以实现`struts2-rest-showcase-2.1.8.war`项目中的功能。 首先,`ModelDriven`接口是Struts2提供的一种设计模式,用于将Action类与...

    struts2-showcase.rar

    9. **RESTful风格**:如何构建符合REST原则的URL和Action。 10. **S2-005安全漏洞**:Struts2-showcase还包含了一些已知的安全漏洞实例,用于教育开发者如何避免和修复这些漏洞。 通过深入研究和分析struts2-...

    解决struts2支持restful访问url长短不一的问题.txt

    由于老项目用的struts2,需要扩展支持restful访问接口,前提是不要破坏原系统struts的访问方式。网上查了好多方法,都很麻烦。最后使用了最简单也是最有效的方法,解决了大问题。在此提供给大家参考,希望对大家有...

    struts2.1+ rest

    Struts2是一个强大的MVC(Model-View-Controller)框架,它在Java社区中被广泛应用,而REST(Representational State Transfer)是一种网络应用程序的设计风格和开发方式,强调使用HTTP协议来实现资源的交互。...

Global site tag (gtag.js) - Google Analytics