最好的“造假”方式是什么?使用 JAX-RS 的 DELETE 和 PUT 方法?

发布于 2024-08-06 03:37:24 字数 388 浏览 3 评论 0原文

我刚刚开始使用 Jersey 为我的网站创建 RESTful API。这是一个奇妙的改变,我必须自己支持 Java 中的 RESTful 服务。我似乎无法弄清楚的一件事是如何“伪造”DELETE 和 PUT 方法。

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

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

I've just started to use Jersey to create a RESTful API for my site. Its a wonderful change from having to roll my own support for RESTful services in Java. One thing I just can't seem to figure out is how to "fake" a DELETE and PUT method.

Jersey supports the annotations @PUT and @DELETE, however many Load-Balancers will not allow these methods through. In the past I've relied on the ability to define a custom HTTP header (e.g. x-method-override: DELETE) and "tunneling" within a POST request.

Has anyone found a way to bind a method using Jersey/JAX-RS annotations to custom headers? Alternatively, is there a better way around lack of support for PUT and DELETE?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

狼亦尘 2024-08-13 03:37:24

这就是我决定如何处理 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) { ... }

}

Well here is how I've decided to handle the situation within my API. Its relatively simple and doesn't require much additional coding. To illustrate consider a RESTful api for Address:

@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) { ... }

}

不必你懂 2024-08-13 03:37:24

它不再是真正的 REST,但在类似的情况下,我们定义 POST /collection/ 进行插入(正常),POST /collection/{id} 进行更新,POST /collection/{id} 不带正文进行删除。

It's not really REST anymore, but in a similar situation we defined POST /collection/ to be insert (as normal), POST /collection/{id} to be update, POST /collection/{id} without body to be delete.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文