我无法找到正确的@Path

时间:2015-07-19 14:45:08

标签: java jax-rs resteasy

使用JAX-RS,我有以下3 @Path s。

@Path(JobRest.PATH)
@Api(value = JobRest.PATH, description = "REST APIs for Jobs")
public interface JobRest {
    public static final String PATH = "/job";

    @GET
    @Path("/last")
    @Produces(MediaType.APPLICATION_JSON)
    public Job retrieveLastJob(...);

    @GET
    @Path("/{jobId}")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public Job retrieveJob(...., @PathParam("jobId") String jobId, );

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public JobList retrieveAllJobs(....);
}
  • /job正确拨打retrieveAllJobs()
  • /job/1236正确拨打retrieveJob(..., "1236", ...)

我希望/job/last会调用retrieveLastJob(...),因为它匹配,但它会调用retrieveJob(..., "last", ...)

如何更改注释,以便/job/last调用retrieveLastJob(...)

1 个答案:

答案 0 :(得分:3)

TL; DR

删除@Consumes(MediaType.APPLICATION_JSON)方法上的retrieveJob。首先,它不接受身体,所以它不消耗任何东西。其次,它与预期的行为相冲突。

我已经使用Jersey和RESTeasy进行了测试,这似乎是实施方面的差异。 Jersey可以很好地处理您的代码,而RESTeasy总是会遇到retrieveJob方法,就像您遇到的那样。

这是我的看法。如果你看一下JAX-RS spec; 3.7.2 Request Matching,就会有一个用于匹配资源的半神秘算法,就像这样。

  1. 获取所有匹配的资源类(按路径),将它们放入一个集合中。
  2. 获取所有匹配的资源方法(按路径),将它们放入一个集合中。
  3. 按最佳匹配路径对方法进行排序(大多数文字字符先行)。
  4. 按媒体类型排序(消费和生产)。
  5. 从我的角度来看,在这个特殊情况下,在第3步之后,retrieveLastJob应该会自动获胜,因为它具有最多的文字字符。生产媒体类型是相同的,并且消费媒体类型甚至不应该重要,因为它是没有Content-Type的GET请求以进行任何匹配。

    我的猜测RESTeasy仍然使用注释进行排序,即使在这种情况下甚至不应该考虑它。因此,带有注释的方法似乎有更多优先权,因为看起来更具体,只是有一个注释,而另一个没有。但在这种情况下,(第4步)特异性水平确实无关紧要。

    我不知道这是不是违反规范的错误。关于如何处理它并不是很清楚,但我个人认为泽西岛行为是正确的行为,因为在这种特殊情况下这种特异性水平无关紧要。在任何情况下,对于没有正文的GET请求,无论如何都要@Consumes注释是不正确的。