java - 如何将 REST 请求转发到另一个资源?

标签 java rest jersey jax-rs

在我当前的架构中,我有一个位于后面的 JAX-RS 资源:

/categories
/categories/{catId}

是这样实现的:

@Path("/categories")
@Produces("application/json")
public class CategoryResourcesApi {

    @GET
    public Response getCategories() {
        // ...
    }

    @GET @Path("/{catId}")
    public Response getCategory(@PathParam("catId") String catId) {
        // ...
    }

    // ...

}

还有一个服务于:

/products
/products/{prodId}

并有类似的实现:

@Path("/products")
@Produces("application/json")
public class ProductResourcesApi {

    @GET
    public Response getProducts() {
        // ...
    }

    // ...

}

除了这些简单的路径,我还需要提供这些服务:

/categories/{catId}/products
/categories/{catId}/products/{prodId}

这将是与特定类别相关的产品。

最自然的做法是让 ProductResourcesApi 为它们提供服务,但据我了解 JAX-RS 注释结构,这只能由 CategoryResourcesApi 提供服务(或者我认为最终由第三类)。

我在我的资源实现中使用了 @Context 和其他注释,所以我猜直接 new ProductResourcesAPI().getProducts() 是行不通的。

有没有办法在 JAX-RS(或 Jersey)框架内从一个资源路径转发到另一个资源路径?我还有哪些其他选择?如果可能的话,我希望让所有这些都易于维护,这就是为什么我为每个根路径选择一个资源,其中包含子资源。

最佳答案

为此你可以使用 Sub-resource locators ,这基本上是资源类中返回另一个资源类的方法。关于链接中示例的事情是它们自己实例化资源类,例如

@Path("/item")
public class ItemResource {
    @Path("content")
    public ItemContentResource getItemContentResource() {
        return new ItemContentResource();
    }
}

public class ItemContentResource {
    @PUT
    @Path("{version}")
    public void put(@PathParam("version") int version)
    }
}

这有效,但我不确定它是否保留注入(inject),例如,如果您想将 @Context UriInfo 注入(inject)到 ItemContentResource 中的字段中。如果您改为注入(inject)方法参数,它应该可以工作。

为了解决这个问题,有 ResourceContext ,在使用时应保留所有注入(inject)。例如,在您当前的情况下,您可以这样做

@Path("/categories")
@Produces("application/json")
public static class CategoryResourcesApi {

    @Context
    private ResourceContext resourceContext;

    @Path("/{catId}/products")
    public ProductResourcesApi getProducts() {
        return resourceContext.getResource(ProductResourcesApi.class);
    }
}

@Path("/products")
@Produces("application/json")
public static class ProductResourcesApi {

    @Context
    private UriInfo info;

    @GET
    @Path("/{id}")
    public Response getProducts(
            @PathParam("id") String prodId,
            @PathParam("catId") String catId) {
    }
}

getProducts 将映射到 URI /categories/{catId}/products/{prodId}。您只需要检查 catId 是否为空(仅当您需要它进行任何查找时)我想确定该请求是对根产品资源还是对父类别资源的请求。我想为代码重用付出的代价很小。

看看您的评论,我相信过去 Swagger 不支持子资源定位器,但我相信他们现在支持了。如果您有任何问题,您可能需要四处搜索任何讨论。 Here's讨论,和another one , 和 another one

关于java - 如何将 REST 请求转发到另一个资源?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33434299/

相关文章:

java - 在带有父类(super class)的 Lombok 构建器中使用自定义 setter

java - 如何在我的 Web 应用程序中提供 json 输入?

java - 当 jFrame 刷新时,旧的 jPanel 消失

java - 带有 MySQL 数据库的 spring-data-elasticsearch

ajax - JSONP 传递 api key

python - Django ,休息 : Serialize a text or image file to post via HTTP in JSON

java - 使用 Rest 服务找不到 RequestParams

java - 泽西客户端 : too many Conent-Type header values

java - 自定义 SQL 查询以检查 GET-Request 中的列

servlets - Glassfish 4.0.1 上的 Jersey 2.4 : How to inject context HttpServletRequest into ContainerRequestFilter?