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

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

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

您不能在单个方法上使用多个@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(); } } 

使用servletfilter重写URL

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

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

正如Tom的回答中所解释的那样,您不能在单个方法上使用多个@Path注释,因为您将遇到error: duplicate annotation在编译时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(); } 

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

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

  • HTTP:// A / B / C
  • HTTP:// A / B

我们假设:

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

因为完整路径看起来像:

使用可选参数

 @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个子弹点的c (不是/c ),但对于第4 子弹点,它将返回c/必须用Java解析。

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