我们正在构建一个用于 Jersey HTTP 客户端的 RESTful JAXRS 网络服务。我们希望大量使用子资源定位器来防止单个大型源文件中的代码困惑。例如。 (最小示例):
@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 已检测到以下警告:警告:资源(或子资源)资源{"{id} ”,0 个子资源,5 个资源方法,1 个子资源定位器,4 个方法处理程序类,0 个方法处理程序实例},路径为“{id}”,包含(子)资源方法和子资源定位器。资源不能在同一路径上同时定义方法和定位器。定位器将被忽略。
它说定位器将被忽略,但它非常有效。怎么了?顺便说一下,我更希望能够为路径 /places/{id}
使用子资源定位器。它应该只使用子资源类中的 @GET
注释方法;不过,如前所述,这会返回 405 错误代码。
最佳答案
是的,这是非法的。添加子资源时,它也负责管理其根路径。因此对于路径 /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)
}
关于java - 同一路径上的子资源定位器和资源方法是否非法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28752385/