泽西岛:@Consumes在没有设置内容类型时不能正常工作

我想知道@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仅作为filter,否则Jersey会尝试找到最合适的匹配。 这与HTTP规范匹配:

包含实体主体的任何HTTP / 1.1消息应该包括定义该主体的媒体类型的Content-Type头部字段。 当且仅当媒体类型不是由Content-Type字段给出时,接收者可以尝试通过检查其内容和/或用于标识资源的URI的名称扩展来猜测媒体类型。 如果媒体类型仍然未知,则收件人应该将其视为“application / octet-stream”类型。

如果目标是让@Consumes充当白名单,则可以使用servletfilter在没有设置的请求上默认Content-Type。

您应该指定类型 – 例如:

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

基于文档似乎在类级别使用@Consumes没有显式覆盖方法级别定义(默认为*/* ),因此它可能会以附加的方式工作…

您是否尝试在方法定义中应用相同的@Consumes