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

Shi*_*aor 5 java rest annotations jax-rs jersey-2.0

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

@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() {}

}
Run Code Online (Sandbox Code Playgroud)

现在假设我使用下一个标头调用此资源:

<header>
    <name>Accept</name>
    <value>text/html, application/xhtml+xml, */*</value>
</header>
Run Code Online (Sandbox Code Playgroud)

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

Pau*_*tha 2

<header>
    <name>Accept</name>
    <value>text/html, application/xhtml+xml, */*</value>
</header>
Run Code Online (Sandbox Code Playgroud)

我不知道那是什么;标头不是以 XML 形式发送的,但假设您正确发送了标头,则其分解方式如下。

@Produces当客户端发送数据时,处理Accept标头,并@Consumes处理客户端Content-Type标头。所以让我们看看你的两个@Produces注释,针对Accept标题

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

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

text/html, application/xhtml+xml, */*
Run Code Online (Sandbox Code Playgroud)

所以他们都没有text/html,所以把它划掉。他们都没有application/xhtml+xml,所以把它划掉。只剩下*/*,这意味着“给我发送任何东西”。所以泽西岛可以自由选择哪一个。结果是不可预测的。你不能对此做出任何假设。这是客户的错。不是我们的。客户端应该发送正确的标头。或者也许我们应该更好地记录我们的 API,以便客户知道我们可以生成什么类型​​:-)