Jersey / Jax-RS 如何在资源中选择正确的方法

How does Jersey / Jax-RS picks the right method in a resource

我正在为 API 服务器使用最新版本的 Jersey。 我定义了下一个资源:

@javax.ws.rs.Path("/myPath")
public class MyResource {

  @GET
  @Consumes({MediaType.WILDCARD, MediaType.TEXT_PLAIN, MediaType.TEXT_HTML})
  @Produces(MediaType.TEXT_PLAIN)
  public Response method1(@Context Request request) {
  }

  @GET
  @Consumes(MediaType.APPLICATION_JSON)
  @Produces(MediaType.APPLICATION_JSON)
  public MyObject method2() {}

}

现在假设我用下一个 header:

调用此资源
<header>
    <name>Accept</name>
    <value>text/html, application/xhtml+xml, */*</value>
</header>

在没有方法 Producer 注释匹配的情况下,Jersey 如何知道要匹配哪一个? 我问是因为有一次服务器响应了 method2 并且在重新启动它之后,它响应了 method1。

<header>
    <name>Accept</name>
    <value>text/html, application/xhtml+xml, */*</value>
</header>

我不知道那是什么; header 未在 XML 中发送,但假设您正确发送了 header,下面是它的分解方式。

当客户端发送数据时,

@Produces处理Acceptheader,@Consumes处理客户端Content-Typeheader。那么让我们看看你的两个 @Produces 注释,针对 Accept header

@Produces(MediaType.TEXT_PLAIN)
public Response method1() {}

@Produces(MediaType.APPLICATION_JSON)
public MyObject method2() {}

text/html, application/xhtml+xml, */*

所以他们都没有 text/html,所以把它划掉。他们都没有 application/xhtml+xml,所以把它划掉。那只剩下 */*,这意味着 "send me whatever"。 所以泽西岛可以自由选择。结果是不可预测的。您不能对此做出任何假设。 那是客户的错。不是我们的。客户端应该发送正确的 header。或者也许我们应该更好地记录我们的 API,这样客户就知道我们可以生产什么类型 :-)

我 运行 遇到了同样的问题,我必须使用特定的 @Produces() 注释来处理方法。这个技巧有效:

@Produces(MediaType.APPLICATION_JSON)
public Response method1() {}

@Produces({MediaType.TEXT_PLAIN, "*/*;q=0"})
public Response method2() {}

使用 MIME 类型时,可以添加 q 属性,表示优先级(0 到 1)。 q 属性 的缺失意味着 1,但显然 q=0 欺骗 Jersey 使用其他函数。

这有点像 hack,所以我不知道它是否会继续工作,但帮助了我。