问题描述
在我目前的架构中,我有一个JAX-RS资源,它位于后面:
In my current architecture, I have a JAX-RS resource that sits behind:
/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() {
// ...
}
// ...
}
除了这些简单的路径,我还需要提供这些:
Apart from these straightforward paths, I also need to serve these:
/categories/{catId}/products
/categories/{catId}/products/{prodId}
这是与特定类别相关的产品。
which would be products related to a specific category.
最自然的事情是make ProductResourcesApi
为它们提供服务,但按照我理解JAX-RS注释结构的方式,这只能由 CategoryResourcesApi (或者最终由第三类,我认为)。
The most natural thing to do would be make
ProductResourcesApi
serve them, but by the way I understand the JAX-RS annotations structure, this can only be served by CategoryResourcesApi
(or eventually by a third class, I think).
我正在使用
@Context
和其他注释在我的资源实现中,所以直接 new ProductResourcesAPI()。getProducts()
不会起作用,我想。
I'm using
@Context
and other annotations in my resource implementations, so a direct new ProductResourcesAPI().getProducts()
wouldn't work, I guess.
有没有办法在JAX-RS(或Jersey)框架内从一个资源路径转发到另一个资源路径?我还有其他选择吗?如果可能的话,我想保持所有这些易于维护,这就是为什么我为每个根源路径选择一个资源,其中有子资源。
Is there any way to forward from one resource path to another within the JAX-RS (or Jersey) framework? What other options do I have? I'd like to keep all this easily maintainable if possible, that's why I chose one resource for each root path with subresources within.
推荐答案
子资源定位器,基本上是资源类中返回另一个资源类的方法。关于链接中的示例的事情是它们自己实例化资源类,例如
For this you can use Sub-resource locators, which is basically a method in the resource class that returns another resource class. The thing about the examples in the link is that they instantiate the resource class themselves, for example
@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)
}
}
,但我不确定它是否会保留注射,例如,如果您想将
@Context UriInfo
注入 ItemContentResource 。如果你注入方法参数,它应该可以工作。
which works, but I am not sure if it preserves injections, for instance if you wanted to inject
@Context UriInfo
into a field in ItemContentResource
. It should work though if you injected into the method param instead.
为了解决这个问题,有一个,在使用时应保留所有的注射。例如,在你目前的情况下,你可以做到
To get around this, there is the
ResourceContext
, which when used, should preserve all the injections. For example in your current case, you can do
@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
是否为空(仅当您需要它进行任何查找时)我想确定该请求是否是对根产品资源的请求或到父类别资源。代码重用的代价很小我想。
The
getProducts
would map to the URI /categories/{catId}/products/{prodId}
. You just need to check if the catId
is null (only if you need it to do any lookup) I guess to determine if the request is a request to the root products resource or to the parent categories resource. Small price to pay for code reuse I guess.
只看你的评论,我相信过去Swagger不支持子资源定位器,但我相信现在他们做了。如果您遇到问题,可能需要搜索任何讨论。 讨论,,
And just looking at your comment, I believe in the past Swagger didn't support sub-resource locators, but I believe now they do. You may want to search around for any discussions if you have problems with it. Here's a discussion, and another one, and another one
这篇关于如何将REST请求转发到另一个资源?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!