2012-02-23 6 views
13

Tengo dos clases REST para un servicio web simple (Jersey y GlassFish) que involucra recursos de usuario: uno para operar en todos los usuarios (por ejemplo, una fábrica para @POSTing) y otro para usuarios individuales (por ejemplo, @GET, @PUT , @BORRAR). Están en:¿Cómo obtengo JAX-RS @Path de un recurso diferente durante un POST?

@Stateless @Path("users") public class AllUsersResource {...} 
@Stateless @Path("user") public class OneUserResource {...} 

respectivamente. Al exponer AllUsersResource quiero devolver la ubicación (a través de Response.created(uri).build()) del nuevo usuario, por ejemplo,

http://localhost:8080/.../user/152 

Mi pregunta es cómo hacer esto. AllUsersResource inyecta @Context UriInfo uriInfo, pero eso no me proporciona información de @Path para OneUserResource, solo la de la llamada actual ("usuarios"). La forma en que finalmente se consiguió poner en funcionamiento era simplemente utilizar la reflexión, pero me preocupa es frágil y impuro:

OneUserResource.class.getAnnotation(Path.class).value(); 

Buscando Stackoverflow las únicas otras cosas que encontré a tratar fueron los siguientes, sin éxito:

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

¡Cualquier ayuda sería excelente!

Respuesta

8

Encontré un par de métodos javax.ws.rs.core.UriBuilder que hicieron el truco, que quería compartir en caso de que otros tuvieran esta pregunta. Son: UriBuilder.fromResource (OneUserResource.class) y javax.ws.rs.core.UriBuilder.path (Class). He utilizado este último en una llamada de una sola vez:

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

El problema con ambos métodos es que ambos requieren clases de recursos ** root ** para que funcionen. No funcionarán si los usa desde un sub-recurso (se lanza 'IllegalArgumentException'). Entonces, si usó un sub-recurso que manejó la solicitud POST; y si desea devolver un '201' con el encabezado' Ubicación', todavía no ha tenido suerte :( – curioustechizen

5

Con el concepto RESTO estricta se puede hacer como una raíz de recursos

@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") 
@Stateless 
public class UsersResouce { 

    // /users 
    @POST 
    @Consumes({MediaType.APPLICATION-XML, MediaType.APPLICATION-JSON}) 
    public Response createUser(final User user) { 
     // persist the user here 
     return Response.created("/" + user.getId()).build(); 
    } 

    // /users 
    @GET 
    @Produces({MediaType.APPLICATION-XML, MediaType.APPLICATION-JSON}) 
    public Response readUsers() { 
     //return all users 
    } 

    // /users/{id} 
    @GET 
    @Path("/{user_id: \\d+}") 
    @Produces({MediaType.APPLICATION-XML, MediaType.APPLICATION-JSON}) 
    public Response readUser(
     @PathParam("user_id") final Long userId) { 

     final User persisted = userBean.find(userId); 

     if (persisted == null) { 
      return Response.status(Status.NOT_FOUND).build(); 
     } 

     return Response.ok().entity(persisted).build(); 
    } 

    // /users/{id} 
    @Consumes({MediaType.APPLICATION-XML, MediaType.APPLICATION-JSON}) 
    @PUT 
    @Path("/{user_id: \\d+}") 
    public Response updateUser(
     @PathParam("user_id") final Long userId, 
     final User mergeable) { 

     final User persisted = userBean.find(userId); 

     if (persisted == null) { 
      userBean.persist(mergeable); 
     } else { 
      persist.setName(mergeable.getName()); 
      userBean.merge(persisted); 
     } 

     return Response.status(Status.NO_CONTENT).build(); 
    } 

    // /users/{id} 
    @DELETE 
    @Path("/{user_id: \\d+}") 
    public Response deleteUser(
     @PathParam("user_id") final Long userId) { 

     userBean.delete(userId); 

     return Response.status(Status.NO_CONTENT).build(); 
    } 

    @EJB 
    private UserBean userBean; 
} 
13

Puede utilizar UriBuilder.fromresource(), pero esto solo funciona si la clase de recursos suministrada es un recurso raíz (esto se menciona claramente en los javadocs). Encontré una forma de lograr esto incluso si está en una clase de recursos secundarios:

@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(); 
} 
+1

esto devolvería 'http: // localhost: 8080/project/users/152' en lugar de' http:// localhost: 8080/project/user/152' mientras que el último es lo que se necesita para SO –

Cuestiones relacionadas