簡體   English   中英

澤西島:@Consumes在沒有設置內容類型時不起作用

[英]Jersey: @Consumes doesn't quite work when content-type is not set

我想知道@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呢?

基於@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 )加上你看到的行為我認為結束以下Jersey實現是安全的:

如果客戶端未設置Content-Type,則Jersey不會默認,但允許它通過任何/所有@Consumes注釋。

當為URI設置多個@Consumes {不同類型}且客戶端未設置Content-Type時,Jersey將默認為第一個@Consumes注釋或首先在可接受類型列表中鍵入。

當設置Accepts標頭值時,Jersey將找到最適合執行的方法。 如果多種方法最適合,則默認為第一次定義。

總之,如果客戶端設置Content-Type,@ Consumes僅作為過濾器,否則Jersey會嘗試找到最合適的匹配。 這與HTTP規范匹配:

包含實體主體的任何HTTP / 1.1消息應該包括定義該主體的媒體類型的Content-Type頭部字段。 當且僅當媒體類型不是由Content-Type字段給出時,接收者可以嘗試通過檢查其內容和/或用於標識資源的URI的名稱擴展來猜測媒體類型。 如果媒體類型仍然未知,則收件人應該將其視為“application / octet-stream”類型。

如果目標是讓@Consumes充當白名單,則可以使用servlet過濾器在沒有設置的請求上默認Content-Type。

基於文檔似乎在類級別使用@Consumes沒有顯式覆蓋方法級別定義(默認為*/* ),因此它可能會以附加方式工作...

您是否嘗試在方法定義中應用相同的@Consumes

您應該指定類型 - 例如:

ClientResponse res =
    service.path("accounts")
        .type("application/vnd.dsu.account+json")
        .post(ClientResponse.class,ent);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM