我们可以为同一个REST方法使用多个@Path注释吗?

时间:2013-06-08 13:54:18

标签: java rest jersey jax-rs

我们可以为同一个REST方法提供多个@Path注释,即执行的方法是相同的,但是在访问多个URL时执行它?

例如:我想在searchNames()http://a/b/c上运行http://a/b方法。

4 个答案:

答案 0 :(得分:43)

您不能在单个方法上使用mutliple @Path注释。它会导致“重复注释”语法错误。

但是,有很多方法可以有效地将两个路径映射到方法。

@Path注释中的正则表达式

JAX-RS中的@Path注释接受参数,其值可以使用正则表达式进行限制。

此注释:

@Path("a/{parameter: path1|path2}")

可以通过/a/path1/a/path2的请求启用该方法。如果需要使用子路径,请使用转义斜杠:{a:path1\\/subPath1|path2\\/subPath2}

使用重定向状态代码

提供响应

或者,您可以设置重定向。这是通过定义另一个子资源在Jersey(JAX-RS的参考实现)中实现它的方法。这只是一个例子,如果你喜欢不同的处理重定向的方法,请随意使用它。

@Path("basepath")
public class YourBaseResource {

  //this gets injected after the class is instantiated by Jersey    
  @Context
  UriInfo uriInfo; 

  @Path("a/b")
  @GET
  public Responce method1(){
    return Response.ok("blah blah").build();
  }

  @Path("a/b/c")
  @GET
  public Response method2(){
    UriBuilder addressBuilder = uriInfo.getBaseUriBuilder();
    addressBuilder.path("a/b");
    return Response.seeOther(addressBuilder.build()).build();
  }

}

使用servlet过滤器重写URL

如果您经常需要这样的功能,我建议使用servlet过滤器拦截传入的请求并动态重写路径。这应该可以帮助您将所有重定向保留在一个位置。理想情况下,您可以使用现成的库。 UrlRewriteFilter只要您使用BSD许可证就可以了(请查看他们的Google代码网站了解详情)

另一种选择是通过在Java应用程序前设置代理来处理此问题。您可以设置Apache服务器以提供基本的缓存和重写规则,而不会使Java代码复杂化。

答案 1 :(得分:13)

正如Tom's answer中所述,您不能在单个方法上使用多个@Path注释,因为您将在编译时遇到error: duplicate annotation

我认为解决这个问题的最简单方法是使用方法重载:

@Path("{foo}")
public Response rest(@PathParam("foo") final String foo) {
    return this.rest(foo, "");
}

@Path("{foo}/{bar}")
public Response rest(@PathParam("foo") final String foo,
                     @PathParam("bar") final String bar) {
    return Response.ok(foo + " " + bar).build();
}

如果遇到多个重载方法都有签名的情况,也可以使用更多不同的方法名称。

答案 2 :(得分:6)

针对您的特定示例的另一种解决方案:

我们假设:

  • /a用于资源类
  • /b/c/b是方法的路径

因为完整路径如下所示:

<protocol><host><port><app><url-pattern><resource-path><method-path>

使用可选参数

@Path("/b{c : (/c)?}")
public Response searchNames(@PathParam("c") String val) {
    ...
}

以上示例适用于所有示例:

  • /b
  • /b/
  • /b/c
  • /b/c/

但是在提供c时,val/c(之前有/)。

如果你想解决上面的问题(为了避免Java解析),你需要更复杂的东西:

@Path("/b{slash : (/)?}{c:((?<=/).*)?}")

对于3 rd 项目符号点仅返回c(不是/c),但对于4 th 项目符号点,它将返回返回必须用Java解析的c/

但是对于你的情况(“执行的方法是相同的”),不要担心解析,因为你没有不同的行为。

答案 3 :(得分:0)

如果您使用的是Spring,请尝试@RequestMapping(value = {“ / def”,“ / abc”},方法= RequestMethod.POST)。 / abc和/ def都将work

sSaroj 17年11月17日在10:13