简体   繁体   English

如何在JAX-RS中处理多个子资源?

[英]How to deal with multiple sub resources in JAX-RS?

I have a JAX-RS REST API with several sub resources eg 我有一个带有几个子资源的JAX-RS REST API,例如

users/{user_id}/posts/{post_id}/comments/{comment_id} . users/{user_id}/posts/{post_id}/comments/{comment_id} The resources are divided into individual classes ( UsersResource , UserResource , PostsResource , etc.) and accessed via sub resource locators. 这些资源分为各个类( UsersResourceUserResourcePostsResource等),并可以通过子资源定位器进行访问。 Each resource uses a correlating service ( UserService , PostService , CommentService ) to access the database. 每个资源都使用关联服务( UserServicePostServiceCommentService )来访问数据库。

How would I go about realising this? 我将如何实现呢? I tried to search for an example but was only able to find very basic ones. 我试图搜索一个示例,但只能找到非常基本的示例。

I already implemented several approaches but they all "feel" wrong. 我已经实现了几种方法,但是它们都“感觉”到了错误。

One was to inject all services in the root resource and pass them along. 一种是将所有服务注入到根资源中并传递它们。 But it seems wasteful to instantiate all services although only the first might be needed. 实例化所有服务似乎很浪费,尽管可能只需要第一个即可。

Another was to make all resources @RequestScoped and inject the subsequent resource so the right service can be injected at the right place. 另一个是将所有资源都设置为@RequestScoped并注入后续资源,以便可以在正确的位置注入正确的服务。 But I would need to inject the sub resource in advance even if I didn't need it and I wouldn't be able to pass parameters along. 但是,即使我不需要子资源并且也无法传递参数,我也需要提前注入它。

My current approach fails at not being able to inject the service inside my sub resource. 我当前的方法无法将服务注入到我的子资源中。 (see below) (见下文)

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));
    }

service example 服务实例

@Stateless
public class UserService {

    @PersistenceContext
    private EntityManager em;

    (...)
}

Maybe a bit late, but the answer to this is still hard to find. 也许有点晚了,但是仍然很难找到答案。

To Inject EJBs directly in subresources, annotate the subresource with @Provider, it could also be a good idea to append @Produces. 要直接在子资源中注入EJB,用@Provider注释子资源,最好附加@Produces。

So your 所以你

public class PostsResource() {

becomes

@Provider
@Produces(MediaType.APPLICATION_JSON)
public class PostsResource() {

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM