14

ここで @Consumes がどのように機能するかを理解しようとしています。

以下のような単純化されたリソースがあり、このリソースで「application/vnd.myApp+xml」のみを使用したいと考えています。

@Path("/app")
@Consumes("application/vnd.myApp+xml")
@Produces("application/vnd.myApp+xml")
public class AppResource {
    @POST
    public Response postStuff() {
        ...
    }
}

私は次のテストケースを持っています:-

public class AppResourceTest extends JerseyTest {
    @Test
    public void testApp() {
        // #1: Works fine
        ClientResponse response = resource().path("app")
                    .accept("application/vnd.myApp+xml")
                    .post(ClientResponse.class);

        ...

        // #2: Throws a 415 Unsupported Media Type
        ClientResponse response = resource().path("app")
                    .accept("application/vnd.myApp+xml")
                    .type("text/plain")
                    .post(ClientResponse.class);

        ...

        // #3: Works fine
        ClientResponse response = resource().path("app")
                    .accept("application/vnd.myApp+xml")
                    .type("application/vnd.myApp+xml")
                    .post(ClientResponse.class);

        ...
    }
}

上記の 3 つのテストから、#2 と #3 は期待どおりに機能します。

#1 については、コンテンツ タイプを設定しないと、415 もスローされないのはなぜですか?

4

3 に答える 3

9

@Consumes api ( http://jsr311.java.net/nonav/releases/1.0/javax/ws/rs/Consumes.html ) および HTTP タイプ仕様 ( http://www.w3.org/Protocols/ ) に基づくrfc2616/rfc2616-sec7.html#sec7.2.1 ) が表示されている動作と相まって、次のジャージー実装を結論付けても安全だと思います。

Content-Type がクライアントによって設定されていない場合、Jersey はデフォルトではありませんが、任意/すべての @Consumes アノテーションを通過することを許可します。

複数の @Consumes {異なるタイプ} が URI に設定されていて、クライアントが Content-Type を設定していない場合、Jersey はデフォルトで最初の @Consumes アノテーションまたは受け入れ可能なタイプのリストの最初のタイプになります。

Accepts ヘッダー値が設定されている場合、Jersey は実行するのに最適な方法を見つけます。複数のメソッドが最適な場合は、最初に定義されたメソッドがデフォルトになります。

結論として、@Consumes は、クライアントが Content-Type を設定する場合にのみフィルターとして機能します。それ以外の場合、Jersey は最適な一致を見つけようとします。これは HTTP 仕様と一致します。

エンティティ本体を含む HTTP/1.1 メッセージには、その本体のメディア タイプを定義する Content-Type ヘッダー フィールドを含める必要があります。メディア タイプが Content-Type フィールドで指定されていない場合に限り、受信者は、リソースの識別に使用される URI のコンテンツおよび/または拡張子の検査を介してメディア タイプを推測しようとしてもよい (MAY)。メディア タイプが不明のままである場合、受信者はそれを「アプリケーション/オクテット ストリーム」タイプとして扱う必要があります (SHOULD)。

目標が @Consumes をホワイト リストとして機能させることである場合、サーブレット フィルタを使用して、何も設定されていないリクエストの Content-Type をデフォルトにすることができます。

于 2013-02-14T16:09:52.320 に答える
2

クラスレベルで使用しているように見えるドキュメントに基づいて、@Consumesメソッドレベルの定義(デフォルトは )を明示的にオーバーライドしない*/*ため、追加的な方法で動作している可能性があります...

@Consumesメソッド定義に同じことを適用しようとしましたか?

于 2012-11-10T05:47:35.993 に答える
2

タイプを指定する必要があります。例:

ClientResponse res =
    service.path("accounts")
        .type("application/vnd.dsu.account+json")
        .post(ClientResponse.class,ent);
于 2012-11-13T09:47:38.513 に答える