Java 如何在发布期间获取不同资源的JAX-RS@Path?

Java 如何在发布期间获取不同资源的JAX-RS@Path?,java,rest,path,jersey,jax-rs,Java,Rest,Path,Jersey,Jax Rs,对于一个涉及用户资源的简单web服务(Jersey和GlassFish),我有两个REST类——一个对所有用户进行操作(例如,@POSTing的工厂),另一个对单个用户进行操作(例如,@GET、@PUT、@DELETE)。它们位于: @Stateless @Path("users") public class AllUsersResource {...} @Stateless @Path("user") public class OneUserResource {...} 分别。发布到AllU

对于一个涉及用户资源的简单web服务(Jersey和GlassFish),我有两个REST类——一个对所有用户进行操作(例如,@POSTing的工厂),另一个对单个用户进行操作(例如,@GET、@PUT、@DELETE)。它们位于:

@Stateless @Path("users") public class AllUsersResource {...}
@Stateless @Path("user") public class OneUserResource {...}
分别。发布到AllUsersResource时,我希望返回新用户的位置(通过
Response.created(uri).build()
),例如

http://localhost:8080/.../user/152
我的问题是如何做到这一点。AllUsersResource注入@Context UriInfo UriInfo,但这不会为OneUserResource获取@Path信息,只获取当前调用(“用户”)的路径信息。我最终让它工作的方法只是简单地使用反射,但我担心它是脆弱和不干净的:

OneUserResource.class.getAnnotation(Path.class).value();
搜索StackOverflow我发现唯一可以尝试的其他事情是以下,但没有成功:

  • com.sun.jersey.api.core.ResourceContext
  • javax.ws.rs.core.UriInfo.getMatchedResources()
  • @javax.inject.inject OneUserResource oneUserRes

任何帮助都太好了

我发现了两个javax.ws.rs.core.UriBuilder方法,我想与大家分享一下,以防其他人有这个问题。它们是:UriBuilder.fromResource(OneUserResource.class)和javax.ws.rs.core.UriBuilder.path(class)。我在一次一次性通话中使用了后者:

URI newUserUri = uriInfo.getBaseUriBuilder().path(OneUserResource.class).path("/" + user.getId()).build();
return Response.created(newUserUri).build();

使用严格的REST概念,您可以将其作为一个根资源

@POST   /users        -> CREATE a single user
@GET    /users        -> READ all users
@PUT    /users        -> UPDATE (REPLACE) all users @@?
@DELETE /users        -> DELETE all users @@?

@POST   /users/{id}   -> CREATE a single user's some other child; @@?
@GET    /users/{id}   -> READ a single user
@PUT    /users/{id}   -> UPDATE a single user
@DELETE /users/{id}   -> DELETE a single user
@Path(“/users”)
@无国籍
公共类用户资源{
///用户
@职位
@使用({MediaType.APPLICATION-XML,MediaType.APPLICATION-JSON})
公共响应createUser(最终用户){
//将用户持久保存在此处
返回响应。已创建(“/”+user.getId()).build();
}
///用户
@得到
@产生({MediaType.APPLICATION-XML,MediaType.APPLICATION-JSON})
公共响应readUsers(){
//返回所有用户
}
///users/{id}
@得到
@路径(“/{user\u id:\\d+}”)
@产生({MediaType.APPLICATION-XML,MediaType.APPLICATION-JSON})
公共响应读用户(
@PathParam(“用户id”)最终长用户id){
最终用户持久化=userBean.find(userId);
if(持久化==null){
返回Response.status(status.NOT_FOUND).build();
}
返回Response.ok().entity(persisted.build();
}
///users/{id}
@使用({MediaType.APPLICATION-XML,MediaType.APPLICATION-JSON})
@放
@路径(“/{user\u id:\\d+}”)
公共响应更新程序(
@PathParam(“用户id”)最终长用户id,
最终用户(可合并){
最终用户持久化=userBean.find(userId);
if(持久化==null){
persist(可合并);
}否则{
persist.setName(mergeable.getName());
合并(持久化);
}
返回Response.status(status.NO_CONTENT.build();
}
///users/{id}
@删除
@路径(“/{user\u id:\\d+}”)
公共响应删除用户(
@PathParam(“用户id”)最终长用户id){
delete(userId);
返回Response.status(status.NO_CONTENT.build();
}
@EJB
私有用户bean用户bean;
}

您可以使用UriBuilder.fromresource(),但这仅在提供的资源类是根资源的情况下有效(这在javadocs中有明确说明)。我找到了一种方法来实现这一点,即使您属于子资源类:

@POST
@Consumes({MediaType.APPLICATION-XML, MediaType.APPLICATION-JSON})
public Response createUser(final User user, @Context UriInfo uriInfo) {
    // persist the user here
    URI uri = uriInfo.getAbsolutePathBuilder().path(user.getId()).build();
    return Response.created(uri).build();
}

从JAX-RS 2.0开始,最正确的方法(据我所知)是使用如下生成器方法:

    String uri = uriInfo.getBaseUriBuilder()
      .path(ODataV4Endpoint.class)
      .path(ODataV4Endpoint.class, "serviceEndpointJSONCatalog")
      .resolveTemplate("endpointId", endpointId).build().toString();
仅供参考,在本例中,我需要调用path两次,一次用于类上的path注释,第二次用于方法上的注释。我怀疑对该方法的调用可以同时实现这两个功能,但事实并非如此

端点服务EndpointJSonCatalog上的路径注释声明了一个参数,如:“endpoint/{endpointId}”,因此需要调用resolveTemplate。否则,您只需调用path(类cl,String方法)


在我的例子中,我创建了一个生成器和一个符号方法来引用这些方法,以便编译器/运行时能够检查它们。

这两个方法的问题是它们都需要根资源类才能工作。如果您从子资源使用它们,它们将不起作用(
IllegalArgumentException
被抛出)。因此,如果您使用了处理POST请求的子资源;如果您想返回带有
位置
标题的
201
,您仍然运气不佳:(这将返回
http://localhost:8080/project/users/152
而不是
http://localhost:8080/project/user/152
后者才是需要的,所以这个老问题今天与我有关。直接使用路径注释时要小心,因为其中可能有无法转换的表达式或路径参数e直接插入路径,例如,“service/{username}”、“service/{empId:[0-9]+}”。