[英]Jersey: @Consumes doesn't quite work when content-type is not set
I'm trying to figure out how @Consumes works here. 我想知道@Consumes如何在这里工作。
I have a simplified resource that looks like the below, and I only want this resource to consume "application/vnd.myApp+xml". 我有一个简化的资源,如下所示,我只希望这个资源使用“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);
...
}
}
From the 3 tests above, #2 and #3 work as expected. 从上面的3个测试中,#2和#3按预期工作。
As for #1, if I don't set the content-type, why doesn't it throw a 415 too? 对于#1,如果我没有设置内容类型,为什么不抛出415呢?
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: 基于@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实现是安全的:
If the Content-Type is NOT set by the client Jersey does NOT default but allows it to pass through any/all @Consumes annotions. 如果客户端未设置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. 当为URI设置多个@Consumes {不同类型}且客户端未设置Content-Type时,Jersey将默认为第一个@Consumes注释或首先在可接受类型列表中键入。
When the Accepts header value is set Jersey will find the best fitting method to execute. 当设置Accepts标头值时,Jersey将找到最适合执行的方法。 If multiple methods are a best fit it will default to the first defined.
如果多种方法最适合,则默认为第一次定义。
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. 总之,如果客户端设置Content-Type,@ Consumes仅作为过滤器,否则Jersey会尝试找到最合适的匹配。 This does match the HTTP spec:
这与HTTP规范匹配:
Any HTTP/1.1 message containing an entity-body SHOULD include a Content-Type header field defining the media type of that body.
包含实体主体的任何HTTP / 1.1消息应该包括定义该主体的媒体类型的Content-Type头部字段。 If and only if the media type is not given by a Content-Type field, the recipient MAY attempt to guess the media type via inspection of its content and/or the name extension(s) of the URI used to identify the resource.
当且仅当媒体类型不是由Content-Type字段给出时,接收者可以尝试通过检查其内容和/或用于标识资源的URI的名称扩展来猜测媒体类型。 If the media type remains unknown, the recipient SHOULD treat it as type "application/octet-stream".
如果媒体类型仍然未知,则收件人应该将其视为“application / octet-stream”类型。
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充当白名单,则可以使用servlet过滤器在没有设置的请求上默认Content-Type。
Based on the docs it seems using @Consumes
at the class level does not explicitly override method level definitions (which default to */*
), so it stands to reason it may be working in an additive manner... 基于文档似乎在类级别使用
@Consumes
没有显式覆盖方法级别定义(默认为*/*
),因此它可能会以附加方式工作...
Have you tried applying the same @Consumes
on the method definition? 您是否尝试在方法定义中应用相同的
@Consumes
?
You should specify the type- for example: 您应该指定类型 - 例如:
ClientResponse res =
service.path("accounts")
.type("application/vnd.dsu.account+json")
.post(ClientResponse.class,ent);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.