用Restful2ActionMapper让Struts2支持REST风格的URL映射 (转)

用Restful2ActionMapper让Struts2支持REST风格的URL映射 (转)
现在,我们配置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. public class ArticleAction {
  3. private String year, month, id;
  4. ...
  5. getter/setter methods for year,month,id
  6. ...
  7. public String view() { ... }
  8. public String index() { ... }
  9. public String create() { ... }
  10. public String update() { ... }
  11. public String remove() { ... }
  12. }

然后我们需要配置这个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风格。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12467/viewspace-148270/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/12467/viewspace-148270/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值