Как получить JAX-RS @Path другого ресурса во время POST?
У меня есть два класса REST для простого веб-сервиса (Jersey и GlassFish), который включает в себя пользовательские ресурсы - один для работы со всеми пользователями (например, factory для @POSTing), а другой - для отдельных пользователей (например, @GET, @PUT, @DELETE). Они находятся по адресу:
@Stateless @Path("users") public class AllUsersResource {...}
@Stateless @Path("user") public class OneUserResource {...}
соответственно. Когда POSTing на AllUsersResource, я хочу вернуть местоположение (через Response.created(uri).build()
) нового пользователя, например,
http://localhost:8080/.../user/152
Мой вопрос - как это сделать. AllUsersResource внедряет @Context UriInfo uriInfo, но это не дает мне информацию @Path для OneUserResource, только для текущего вызова ( "пользователи" ). То, как я, наконец, получил это, было просто использовать отражение, но я беспокоюсь, что он хрупкий и нечистый:
OneUserResource.class.getAnnotation(Path.class).value();
Поиск StackOverflow - единственное, что я нашел, чтобы попробовать, было без успеха:
- com.sun.jersey.api.core.ResourceContext
- javax.ws.rs.core.UriInfo.getMatchedResources()
- @javax.inject.Inject OneUserResource oneUserRes;
Любая помощь будет потрясающей!
Ответы
Ответ 1
Вы можете использовать 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();
}
Ответ 2
Я нашел пару javax.ws.rs.core.UriBuilder методов, которые сделали трюк, который я хотел бы поделиться, если у других был этот вопрос. Это: UriBuilder.fromResource(OneUserResource.class) и javax.ws.rs.core.UriBuilder.path(класс). Я использовал последнее в одноразовом вызове:
URI newUserUri = uriInfo.getBaseUriBuilder().path(OneUserResource.class).path("/" + user.getId()).build();
return Response.created(newUserUri).build();
Ответ 3
С помощью строгой концепции 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 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;
}