问题描述
我正在试图弄清楚@Consumes如何在这里工作。
I'm trying to figure out how @Consumes works here.
我有一个简化的资源,如下所示,我只希望这个资源消耗应用程序/ vnd.myApp + xml 的。
I have a simplified resource that looks like the below, and I only want this resource to consume "application/vnd.myApp+xml".
@Path("/app")
@Consumes("application/vnd.myApp+xml")
@Produces("application/vnd.myApp+xml")
public class AppResource {
@POST
public Response postStuff() {
...
}
}
我有以下测试用例: -
I have the following testcases:-
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按预期工作。
From the 3 tests above, #2 and #3 work as expected.
至于#1,如果我没有设置内容类型,为什么不抛出415呢?
As for #1, if I don't set the content-type, why doesn't it throw a 415 too?
推荐答案
基于@Consumes api()和HTTP类型规范()加上您看到的行为我认为结束以下Jersey实现是安全的:
Based on @Consumes api (http://jsr311.java.net/nonav/releases/1.0/javax/ws/rs/Consumes.html) and the HTTP type spec (http://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.2.1) coupled with the behavior you are seeing I think it is safe to conclude the following Jersey implementation:
如果Content-Type未由客户端设置,则Jersey不会默认但允许它通过任何/所有@Consumes注释。
If the Content-Type is NOT set by the client Jersey does NOT default but allows it to pass through any/all @Consumes annotions.
当为URI设置了多个@Consumes {不同类型}且客户端未设置Content-Type时,Jersey将默认为第一个@Consumes注释或第一个输入可接受类型列表。
When multiple @Consumes {different types} are set for the URI and the client has NOT set the Content-Type then Jersey will default to the first @Consumes annotation or first type in a list of acceptable types.
当设置Accepts标头值时,Jersey将找到最适合执行的方法。如果多个方法最合适,它将默认为第一个定义。
When the Accepts header value is set Jersey will find the best fitting method to execute. If multiple methods are a best fit it will default to the first defined.
总之,如果客户端设置内容,@ Consumes仅作为过滤器使用 - 否则泽西将尝试找到最合适的匹配。这与HTTP规范匹配:
In conclusion the @Consumes only acts as a filter if and ONLY if the client sets the Content-Type otherwise Jersey will attempt to find the best fitting match. This does match the HTTP spec:
如果目标是将@Consumes作为白名单,然后可以使用servlet过滤器在没有设置的请求中默认Content-Type。
If the goal is to have the @Consumes to act as a white list then a servlet filter could be used to default the Content-Type on requests where none is set.
这篇关于泽西岛:@Consumes在没有设置内容类型时不能正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!