0

ジャージバージョン 1.17.1 + tomcat 7.0.39 + Spring MVC 3.2.1 を使用しています。

問題は、GET ハンドラーの @Path を拡張すると PUT ハンドラーが動作しなくなる理由を理解できないことです。

Spring MVC コントローラーでの次の構成/マッチングは、期待どおりに機能します。

 @GET
 @Path("/{id}")   // <--- WORKS!
 [...]

 @PUT
 @Path("/{id}")   // <--- WORKS!  
 [...]      

しかし、GETハンドラーのマッチングを拡張するたびに、処理できるようにするだけでなく、

/anyId    

リクエストだけでなく、フォームのリクエストも

/anyId/
/anyId/anyfile.ext

その後、PUT マッチングが機能しなくなることに触れていません。

 @GET
 @Path("/{id:.*[^/]}{fileName:.*}")   // <--- WORKS!
 [...]

 @PUT
 @Path("/{id}")                       // <--- Not working any longer: 
                                      //      "405 Method Not Allowed" 
 [...]

GET パスの一致を上記の一致に変更した後、PUT 要求は「405 Method Not Allowed」ステータス コードを取得します。

最初のケースのように GET パスを単純化すると、PUT ハンドラーが再び機能し始めます。

ジャージーのバグか何か?

4

2 に答える 2

1

405 は、そのリソースのリクエストにあったものと一致するメソッドがなかったことを示します。これは、何か(または複数のもの) に一致する@Pathアノテーションがあったが、その (Java) メソッドには正しいメソッドがなかったことを示します。(可能であれば、何が起こっているのかを確認するときに詳細デバッグをオンにします。これは役に立ちます。ただし、完了したらオフにします。通常はオンのままにしておくには冗長すぎます。)

ここで、 がリクエスト内のパスに一致する正規表現にマップされていることを理解するのに役立ち@Pathます。特に指定しない場合、パス テンプレートの部分 ( {id}) は正規表現によって効果的に一致します[^?/;]+。つまり、次のようになります。パスの次の部分、クエリ部分、または行列パラメーターに入ることなく、できるだけ多くの文字を使用します。(行列パラメータが何であるかを知りませんか? おそらく知りたくないでしょう!)

これらすべてのフォームに一致させるには:

/anyId    
/anyId/
/anyId/anyfile.ext

HTTP メソッドごとに 2 つの Java メソッドを使用するのが最善です。

@GET @Path("{id}")
…
@GET @Path("{id}/{file:.*}")
…

これは機能しますが、冗長です。


代わりに、リソースを表し、操作が定義されているオブジェクトを返す方が簡単な場合があります。

class MyResource {
    private String id, file;
    MyResource(String id, String file) {
        this.id = id; this.file = file;
    }
    // Can't remember if @Path is needed on these; "/" is a special case IIRC
    @GET @Path("/") @Produces(…)
    public String get() { … }
    @PUT @Path("/") @Produces(…) @Consumes(…)
    public String put(String message) { … }
}
@Path("{id}")
public MyResource getNoPath(@PathParam("id") String id) {
    return new MyResource(id, null);
}
@Path("{id}/{file:.*}")
public MyResource getNoPath(@PathParam("id") String id, @PathParam("file") String file) {
    return new MyResource(id, file);
}

このように、正しいメソッドを提供するコードからパスを解析するコードを分割します。私はこれを CXF (別の JAX-RS 実装) で行っていますが、かなりうまく機能します。

于 2013-07-25T13:40:10.080 に答える
0

405 は通常、適切なメソッドが見つからなかったことを意味します。あなたが提供した小さなスニペットだけではわかりにくいですが@Consumes、メソッドに適切な注釈があることを確認する必要がありますPUT.

@Pathまた、を次のように変更してみて@Path("{id: [^/]+}/{fileName: .+}")、それが役立つかどうかを確認することもできます。そうでない場合は、完全なコントローラーを提供してください。

于 2013-07-23T15:49:50.003 に答える