有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java我无法找到正确的@Path

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

@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) 个答案

  1. # 1 楼答案

    TL;DR

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


    我已经用Jersey和RESTeasy进行了测试,它的实现似乎有所不同。Jersey可以很好地处理您的代码,而RESTeasy总是按照您的体验使用retrieveJob方法

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

    1. 获取所有匹配的资源类(按路径),将它们放入一个集合中
    2. 获取所有匹配的资源方法(按路径),将它们放入一个集合中
    3. 按最佳匹配路径对方法进行排序(大多数文字字符优先)
    4. 按媒体类型排序(使用消费品和产品)

    从我的角度来看,在这个特殊的例子中,在第3步之后,retrieveLastJob应该会自动获胜,因为它有最多的文字字符。生产媒体类型是相同的,而消费媒体类型应该无关紧要,因为它是一个GET请求,没有内容类型来进行任何匹配

    我猜RESTeasy仍然使用注释进行排序,尽管在本例中不应该考虑它。因此,带有注释的方法似乎被赋予了更高的优先级,因为它通过只包含注释而显得更具体,而另一个没有。但在这种情况下,(第4步)特异性水平真的不重要

    我不知道这是否是违反规范的错误。关于如何处理它还不太清楚,但我个人认为Jersey行为是正确的行为,因为一个简单的事实是,在这个特定的情况下,这种特殊性水平不应该重要。无论如何,对于没有正文的GET请求,使用@Consumes注释是不正确的