web-dev-qa-db-ja.com

同じRESTメソッドに対して@Pathアノテーションを複数持つことはできますか

同じRESTメソッド)に対して複数の_@Path_注釈を付けることはできますか?つまり、実行されるメソッドは同じですが、複数のURLにアクセスすると実行されますか?

例:_http://a/b/c_と_http://a/b_の両方でsearchNames()メソッドを実行したい.

31
Unreal user

単一のメソッドに複数の_@Path_注釈を付けることはできません。 「重複した注釈」構文エラーが発生します。

ただし、2つのパスをメソッドに効率的にマップする方法はいくつかあります。

@Pathアノテーションの正規表現

JAX-RSの_@Path_注釈は、正規表現を使用して値を制限できるパラメーターを受け入れます。

この注釈:

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

_/a/path1_と_/a/path2_の両方のリクエストがメソッドに到達できるようにします。サブパスを使用する必要がある場合は、スラッシュをエスケープします:_{a:path1\\/subPath1|path2\\/subPath2}_

リダイレクトステータスコードで応答を提供する

または、リダイレクトを設定できます。ジャージー(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();
  }

}
_

サーブレットフィルターを使用してURLを書き換える

このような機能が頻繁に必要になる場合は、サーブレットフィルターを使用して着信要求をインターセプトし、その場でパスを書き換えることをお勧めします。これにより、すべてのリダイレクトを1か所で管理できます。理想的には、すぐに使用できるライブラリを使用できます。 UrlRewriteFilter は、BSDライセンスに問題がなければ、うまくいくことができます(詳細については、Googleコードサイトをご覧ください)

もう1つのオプションは、Javaアプリの前にプロキシを設定してこれを処理することです。Apacheサーバーを設定して、Javaコード。

44
toniedzwiedz

Tomの答え で説明されているように、コンパイル時に@Pathに遭遇するため、1つのメソッドで複数の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();
}

また、複数のオーバーロードされたメソッドに署名がある場合に遭遇した場合は、さらに異なるメソッド名を使用することもできます。

14
yegeniy

特定の例の別のソリューション:

それを仮定しましょう:

  • /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に対してc/cではなく)のみを返しますrd 箇条書き、ただし4番目 箇条書きは、Javaで解析する必要があるc/を返します。

しかし、あなたの場合( "実行されたメソッドは同じです")、異なるアクションがないので、解析について心配する必要はありません。

6