子资源定位器和资源方法在同一路径上是非法的吗?

时间:2015-02-26 20:43:21

标签: java rest tomcat jax-rs

我们正在构建一个RESTful JAXRS Web服务,以便与Jersey HTTP客户端一起使用。我们想大量使用子资源定位器来防止单个大型源文件中的代码混乱。例如。 (最小例子):

@Path("places")
public class PlacesResource {

    // Use the following to e.g. GET /places/123
    @GET @Path("{id}")
    @Produces("application/json")
    public Response getPlace(@PathParam("id") int id) {
        //...
        return Response.ok(null).build();
    }

    // Use the following to e.g. GET /places/123/comments/42
    @Path("{id}")
    public PlaceResource place(@PathParam("id") int id) {
        Place p = DAO.getInstance().getPlace(id);
        return new PlaceResource(p); // singular (a different resource class)
    }
}

这很好用。删除这些方法中的任何一个都会导致对前导注释中指定的资源的调用不起作用。 (HTTP响应405:不允许使用方法)

但是,使用此设置时,会在Tomcat日志中显示以下警告:

[http-nio-8084-exec-6] org.glassfish.jersey.internal.Errors.logErrors The following warnings have been detected: WARNING: The resource (or sub resource) Resource{"{id}", 0 child resources, 5 resource methods, 1 sub-resource locator, 4 method handler classes, 0 method handler instances} with path "{id}" contains (sub) resource method(s) and sub resource locator. The resource cannot have both, methods and locator, defined on same path. The locator will be ignored.

它说定位器将被忽略,但它非常有用。怎么了?顺便说一句,我更喜欢能够使用子资源定位器,甚至是路径/places/{id}。它应该只使用子资源类中的@GET - 注释方法;如上所述,这会返回405错误代码。

1 个答案:

答案 0 :(得分:2)

是的,这是非法的。添加子资源时,它还负责管理其根路径。因此,对于路径/places/{id},服务将不知道使用哪个(方法或子资源),因为它们都声称管理该路径。确实忽略了子资源定位器,但仅限于那个模糊路径(/places/{id})。路径/places/{id}/other stuff不明确,因为它与GET方法的路径不匹配,因此不会被忽略。

要消除歧义,请尝试修改子资源,使其仅匹配指定地点ID 其他路径组件的路径。我现在无法访问我的IDE进行测试,但这样的事情应该可行:

// Use the following to e.g. GET /places/123/comments/42
@Path("{id}/{otherStuff: [a-zA-Z0-9_/]+}")
public PlaceResource place(@PathParam("id") int id) {
    Place p = DAO.getInstance().getPlace(id);
    return new PlaceResource(p); // singular (a different resource class)
}