2017-06-13 7 views
0

私はJerseyを内部的に使用するDropwizardを使用しています。コントローラーには2つの方法があります。Jersey 2.x - PUTとGETの競合するルート優先度

PUT /garbage/[id1,id2,...idN]は、更新するリソースを表す数値IDのリストであるパスパラメーターを使用することを意図しています。私は正規表現ベースのPathParamを使用しています。私はこの例では正規表現を無視していますが、それは問題ではないと考えていますが、ポイントは1つの数値が正規表現と一致する必要があるということです。

GET /garbage/[id]は、1つのゴミに関するデータを取得します。

方法の違いにもかかわらず、ジャージーは混乱するようです。

curl localhost:8080/garbage/1 

ジャージーは私に405エラーを与えます。 PUTを画像から取り除く(例えば、パスのparam regexを妨害する、または完全に除去する)と、GETエンドポイントは正常に動作します。

JAX-RS 3.7.2にいくつかの詳細があると仮定していますが、これがなぜこのようになるのか説明していますが、何かを理解できません。

は、ここでは、コードです:

@Path("/garbage") 
@Produces(MediaType.APPLICATION_JSON) 
public class GarbageController { 
    private static final Logger LOG = LoggerFactory.getLogger(GarbageController.class); 

    @PUT 
    @Path("/{params: [\\d,]+}") 
    @Consumes(MediaType.APPLICATION_JSON) 
    @Timed 
    public Response updateGarbage(@PathParam("params") List<PathSegment> params) { 
     LOG.warn("updateGarbage"); 
     return Response.status(Response.Status.OK).build(); 
    } 

    @GET 
    @Path("/{garbageId}") 
    public Response getGarbageById(@PathParam("garbageId") long garbageId) { 
     LOG.warn("getGarbage"); 
     return Response.status(Response.Status.OK).build(); 
    } 
} 

答えて

0

@PathSegmentの主な目的は、マトリックスのパラメータを取得するのに便利であるURIのフラグメントを処理することです。方法以下の例の場合:

@GET 
@Path("/book/{id}") 
public String getBook(@PathParam("id") PathSegment id) {...} 

はこの要求を処理できる必要があります:@PathSegment全体URLフラグメントをインターセプト

GET /book;name=EJB 3.0;author=Bill Burke 

のでGETメソッドを無視しているようです。あなたは、単純な文字列の分割とPUT要求にカンマで区切られたIDを処理することができます:あなたはまた、query parametersに要求フォーマットを変更したり、カスタムオブジェクトを処理するためにConverter/Providerを実装することができます

@PUT 
@Path("/{params}") 
@Consumes(MediaType.APPLICATION_JSON) 
@Timed 
public Response updateGarbage(@PathParam("params") String params) { 
    LOG.warn("updateGarbage ", params.split(",")); 
    return Response.status(Response.Status.OK).build(); 
} 

。それらのすべては実装されていないGETの問題を解決する必要があります。

これはGETとPUTの間のルート優先順位のケースではなく、代わりにGETリクエストでは使用できない@Consumesアノテーションに関連していると思います。 DWはこのエンドポイントを無視しているか、デフォルトのPOSTメソッドに変換しています。このメソッドは、GET要求の405応答を説明します。

+1

回答ありがとうございます!残念ながら、\ @Consumesは問題ではありません。 \ @Consumesの有無にかかわらず試してみましたが、動作には何の影響もありません。 (私は最初に\ @Consumesなしでこのコードを書いてから、ランダムな実験として追加してから、それを削除するのを忘れてしまいました。私は戻って、\ @Consumesをサンプルコードから削除します。 –

0

私はこれを理解しましたが、それがなぜ機能するのかを知るためにジャージーには十分には足りませんでした。解決方法は@GETメソッドを書き換えて、@PUTと同じ正規表現構文を使用することです。 Jerseyはメソッドシグネチャの型変換を処理しますが、型変換が失敗した場合は404を返します(つまり、GET /garbage/xyz)。

@PUT 
@Path("/{params: .+}") 
@Consumes(MediaType.APPLICATION_JSON) 
public Response updateGarbage(@PathParam("params") List<PathSegment> params) { 
    LOG.warn("updateGarbage"); 
    return Response.status(Response.Status.OK).build(); 
} 

@GET 
@Path("/{params: .+}") 
public Response getGarbageById(@PathParam("params") long garbageId) { 
    LOG.warn("getGarbage {}", garbageId); 
    return Response.status(Response.Status.OK).build(); 
}