我有一个带有几个子资源的JAX-RS REST API,例如
users/{user_id}/posts/{post_id}/comments/{comment_id}
。资源分为单个类(UsersResource
,UserResource
,PostsResource
等),并通过子资源定位器访问。每个资源都使用关联服务(UserService
,PostService
,CommentService
)来访问数据库。
我将如何实现这一目标?我试图寻找一个例子,但只能找到非常基本的。
我已经实施了几种方法,但他们都感觉到了#34;错。
一种方法是在根资源中注入所有服务并传递它们。但是实例化所有服务似乎很浪费,尽管可能只需要第一个服务。
另一个是制作所有资源@RequestScoped
并注入后续资源,以便可以在正确的位置注入正确的服务。但是我需要提前注入子资源,即使我不需要它,我也不能传递参数。
我当前的方法因无法在我的子资源中注入服务而失败。 (见下文)
root resource (resources/users)
@RequestScoped
@Path("users")
public class UsersResource() {
@Inject
private UserService service;
@Path("{user_id}")
public UserResource getUserResource(@Context ResourceContext context, @PathParam("user_id") Long id) {
User entity = this.service.find(id);
if (entity == null)
throw new WebApplicationException(Response.status(Status.NOT_FOUND).build());
return context.initResource(new UserResource(entity, this.service));
}
}
user sub resource (resources/users/{user_id})
public class UserResource() {
private User entity;
private UserService service;
public UserResource(User entity, UserService service) {
this.entity = entity;
this.service = service;
}
@GET
public Response doGet() {
return Response.ok(entity).build();
}
@Path("posts")
public TodosResource getPostsResource(@Context ResourceContext context) {
return context.initResource(new PostsResource(entity));
}
}
posts sub resource (resources/users/{user_id}/posts)
public class PostsResource() {
@Inject // can't inject here
private PostService service;
private User user;
public PostsResource(User user) {
this.user = user;
}
@POST
public Response doPost(@Context UriInfo info, Post post) {
post.setUser(this.user);
Post entity = this.service.persist(post);
URI uri = info.getAbsolutePathBuilder().path("/" + entity.getId()).build();
return Response.created(uri).entity(entity).build();
}
@Path("{post_id}")
public PostResource getpostResource(@Context ResourceContext context, @PathParam("post_id") Long id) {
Post entity = this.service.find(id);
if (entity == null)
throw new WebApplicationException(Response.status(Status.NOT_FOUND).build());
return context.initResource(new PostResource(entity));
}
服务示例
@Stateless
public class UserService {
@PersistenceContext
private EntityManager em;
(...)
}
答案 0 :(得分:0)
也许有点晚了,但仍然很难找到答案。
要直接在子资源中注入EJB,使用@Provider注释子资源,附加@Produces也是一个好主意。
所以你的
public class PostsResource() {
变为
@Provider
@Produces(MediaType.APPLICATION_JSON)
public class PostsResource() {