2009-09-27 95 views
1

我刚开始使用Jersey为我的网站创建一个RESTful API。这是我们自己支持Java中的RESTful服务的一个奇妙变化。我似乎无法弄清楚的一件事是如何“伪造”DELETE和PUT方法。使用JAX-RS“伪造”DELETE和PUT方法的最佳方法是什么?

Jersey支持注释@PUT和@DELETE,但许多Load-Balancers不允许这些方法通过。在过去,我依靠在POST请求中定义自定义HTTP头(例如x-method-override:DELETE)和“隧道”的能力。

有没有人找到一种方法来将使用Jersey/JAX-RS批注的方法绑定到自定义标头?或者,有没有更好的方法来支持PUT和DELETE?

回答

2

那么这里是我决定如何处理我的API中的情况。它相对简单,不需要额外的编码。为了说明考虑地址一个RESTful API:

@Path("/address") 
public class AddressService { 

    @GET 
    @Produces("application/xml") 
    public StreamingOutput findAll() { ... } 

    @POST 
    @Produces("application/xml") 
    @Consumes("application/x-www-form-urlencoded") 
    public StreamingOutput create(...) { ... } 

    // 
    // This is the alternative to a "PUT" method used to indicate an "Update" 
    // action. Notice that the @Path expects "/id/{id}" which allows 
    // us to bind to "POST" and not get confused with a "Create" 
    // action (see create() above). 
    // 
    @POST 
    @Produces("application/xml") 
    @Consumes("application/x-www-form-urlencoded") 
    @Path("/id/{id}") 
    public StreamingOutput update(@PathParam("id") Long id, ...) { ... } 

    // 
    // This is the typical "GET" method with the addition of a check 
    // for a custom header "x-method-override" which is designed to 
    // look for inbound requests that come in as a "GET" but are 
    // intended as "DELETE". If the methodOverride is set to "DELETE" 
    // then the *real* delete() method is called (See below) 
    // 
    @GET 
    @Produces("application/xml") 
    @Path("/id/{id}") 
    public StreamingOutput retrieve(
     @PathParam("id") Long id, 
     @HeaderParam("x-method-override") String methodOverride) 
    { 
     if (methodOverride != null && methodOverride.equalsIgnoreCase("DELETE")) { 
     this.delete(id); 
     } 

     ... 
    } 


    // 
    // This is the typical "DELETE" method. The onlything special about it is that 
    // it may get invoked by the @GET equivalent is the "x-method-override" header 
    // is configured for "DELETE" 
    // 
    @DELETE 
    @Produces("application/xml") 
    @Path("/id/{id}") 
    public StreamingOutput retrieve(@PathParam("id") Long id) { ... } 

}

+2

嗨。首先是一件小事:删除方法被命名为“检索”。 因为GET请求必须总是安全的,所以使用POST代替GET来代替假DELETE是不是更好。 另一件事:有没有办法使用假的删除和从HTML表单中放置?没有办法添加x-method-override标头。唯一可能的是表单中隐藏的“_method”字段。 – 2010-01-19 10:57:03

+0

伟大的观点。在这一点上我真的没有提出更好的解决方案。隐藏的表单元素非常有限,因为许多帖子包含XML与编码的表单参数。也就是说,我的大部分RESTful服务都是通过XMLHTTPRequest调用的(或者通过像JQuery这样的框架间接调用的),所以设置头文件非常简单而且总是可行。出于这个原因,主要是我坚持我的解决方案。 – ra9r 2010-06-11 00:16:56

1

这不是真正的REST了,但在类似的情况,我们定义了POST /收集/被插入(正常),POST /收集/ {id}要更新,POST /集合/ {id}没有正文要删除。

相关问题