使用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(...)
?
答案 0 :(得分:3)
删除@Consumes(MediaType.APPLICATION_JSON)
方法上的retrieveJob
。首先,它不接受身体,所以它不消耗任何东西。其次,它与预期的行为相冲突。
我已经使用Jersey和RESTeasy进行了测试,这似乎是实施方面的差异。 Jersey可以很好地处理您的代码,而RESTeasy总是会遇到retrieveJob
方法,就像您遇到的那样。
这是我的看法。如果你看一下JAX-RS spec; 3.7.2 Request Matching,就会有一个用于匹配资源的半神秘算法,就像这样。
从我的角度来看,在这个特殊情况下,在第3步之后,retrieveLastJob
应该会自动获胜,因为它具有最多的文字字符。生产媒体类型是相同的,并且消费媒体类型甚至不应该重要,因为它是没有Content-Type的GET请求以进行任何匹配。
我的猜测RESTeasy仍然使用注释进行排序,即使在这种情况下甚至不应该考虑它。因此,带有注释的方法似乎有更多优先权,因为看起来更具体,只是有一个注释,而另一个没有。但在这种情况下,(第4步)特异性水平确实无关紧要。
我不知道这是不是违反规范的错误。关于如何处理它并不是很清楚,但我个人认为泽西岛行为是正确的行为,因为在这种特殊情况下这种特异性水平无关紧要。在任何情况下,对于没有正文的GET请求,无论如何都要@Consumes
注释是不正确的。