在Restlet实战(七)-提交和处理Web Form 中提到,表单(form)的动作(action)仅仅支持GET和POST,所以那里我们如果要通过form提交修改的数据,不得不进入HTTP标准方法POST对应的方法执行。这实际上是不得已而为之的做法。当然,DELETE也不支持,也会调用POST方法。那么有没有什么办法可以访问到真正的PUT和DELETE标准方法对应在Restlet中要执行的方法呢?
是的,客户端可以通过“用重载的POST(overloaded POST)”来仿造PUT和DELETE的办法来绕过此限制。正如<<Restful Web Service>>书的作者所写:“我建议采用一种被如今许多REST式Web框架所采用的方法,即把真正的HTTP方法放到查询字符串里”。
下面就看看在Restlet是如何利用method查询参数在重载的POST(overloaded POST)之上实现PUT和DELETE请求。
Restlet是通过在Application里面调用TunnelService设置方法参数,代码比较简单,如下:
public class UserApplication extends Application{
public UserApplication(){
getTunnelService().setMethodParameter("_method");
}
@Override
public synchronized Restlet createRoot() {
Router router = new Router(getContext());
Route route = router.attach("/{userId}", UserResource.class);
route.extractQuery("query", "test", true);
router.attach("/{userId}/orders", UserOrdersResource.class);
return router;
}
}
基于上面的代码,假设要访问的URI是/users/1,HTTP标准方法是PUT,实际上,就是修改了用户的资料,然后请求到服务器,要求保存修改后的用户数据。表示(representation)里的form代码片断如下:
<form name="form1" action="<%=request.getContextPath()%>/resources/users/1?_method=put" method="POST">
Name:<input type="text" name="name"/><br>
Address:<input type="text" name="address"/><br>
<input type="button" value="Submit" onclick="doSubmit()"/>
</form>
这里,如果提交form,那么UserResource里的PUT方法将被执行。过程很简单,不再多做解释。
不过有两个问题需要注意,也许你看到form里的action是****?_method=put,那么你也许会想,改成_method=hello可以吗,答案是不行的,如果你这么做了,系统会有异常:
java.lang.NoSuchMethodException: com.infosys.restlet.resource.UserResource.allowHello()
那我们能不能象allowPut定义allowHello呢,显而易见是不行的,这又说到REST上去了,HTTP标准方法常用的也就4个,所以,即使你自己定义allowHello,也不行。
另外一个问题,方法参数设置在application,那么如果有非常多的application,那岂不是需要设置很多次?大量的重复工作。
Restlet已经考虑到这点,因为在TunnelService的构造函数里面已经有指定methodParameter=method,这说明,如果不在application里设置,默认应该是method,也就是说,在form的action里,我可以象这样设置:method=put。
但是在之前的系列文章中,我有时候给出的配置如下(即不通过Application):
<bean id="defaultRouter" class="org.restlet.ext.spring.SpringRouter">
<property name="attachments">
<map>
<entry key="/customers">
<bean class="org.restlet.ext.spring.SpringFinder">
<lookup-method name="createResource" bean="customersResource" />
</bean>
</entry>
<entry key="/customers/{customerId}">
<bean class="org.restlet.ext.spring.SpringFinder">
<lookup-method name="createResource" bean="customerResource" />
</bean>
</entry>
<entry key="/users">
<bean class="com.infosys.restlet.application.UserApplication"/>
</entry>
</map>
</property>
</bean>
上述/users是通过配置Application,而/customers和/customers/{customerId}是直接配置Resource,当然了,如果是直接配置Resource,Restlet会自己实例化一个默认的Application。但是根据我的测试,问题恰恰出在这里,如果是我们自己配置的Application,如UserApplication,则上述仿造PUT和DELETE过程没有任何问题,但是如果是直接配置了Resource,则即使在action指定可method=put,始终会调用POST对应的方法,而不会执行仿造的PUT和DELETE方法。
分享到:
相关推荐
NULL 博文链接:https://ajaxcn.iteye.com/blog/438237
RESTLET开发实例(二)使用Component、Application的REST服务
FE助手和Restlet Client .
restlet相关文档
Restlet与Spring 集成
restlet项目
org.restlet.jar
Restlet Client插件是一款运行在chrome内核浏览器上的Web服务测试插件,该插件主要用于测试各种Web服务,能查看网站基本信息、浏览网页代码并能发送HTTP请求来测试网站Web服务,同时支持自动化API场景。用户在安装了...
一个简单的Restlet开发框架的Basic认证的例子
restlet2.1学习笔记项目代码
Restlet所需要的所有jar包 一次下载,以后高枕无忧!
restlet入门helloworld示例
本文是对Restlet官方教程http://restlet.com/learn/tutorial/2.2/的中文翻译。
RESTLET框架学习书籍
Restlet2.0用户指南
基于Spring的Restlet实例 代码和jar包
资源里面包含了Restlet从入门到高级的开发过程,对学习Restlet有很大的帮助
Restlet包括Restlet API和Noelios Restlet Engine(NRE)两部分,NRE是对Restlet API的一种参考实现。这种划分,使得不同实现可以具有同样的API。NRE包括若干HTTP服务器连接器(HTTP server connector),它们都是...
restlet工程示例,restlet工程小例子