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

时间:2016-05-04 20:18:41

标签: 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() {}

}

现在让我说我用下一个标题调用此资源:

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

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

2 个答案:

答案 0 :(得分:1)

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

我不知道那是什么;标题不是以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, */*

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

答案 1 :(得分:0)

我遇到了同样的问题,我需要使用特定@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欺骗泽西岛使用其他功能。

这是一种黑客行为,所以我不知道它是否会继续有效,但帮助了我。