RESTEasy (JAX-RS) 允许通过子资源进行动态调度。例如:
POST /customers/create
{"name":"Smith","country":"jp"}
我们可以有一个根资源来处理路径“/customers”,其方法不使用 HTTP 方法注释,而是使用 @Path("/create") 注释。此方法返回 JAX-RS 查看的资源以继续处理请求。但是,此资源必须处理“/customers/create”路径。
我有一种可以创建不同类型实体的现有情况:
POST /customers/create
{"name":"Smith"}
POST /locations/create
{"name":"Chicago"}
我想添加基于请求正文中的附加属性创建任何类型实体的能力:
POST /entities/create
{"type":"customer","name":"Smith"}
本质上我想将请求转发到代码处理“POST /customers/create”。我可以编写子资源定位器,该定位器被“POST /entities/create”调用并返回 Customer 资源,但 JAX-RS 无法分派请求,因为 Customer 资源不处理路径“/entities/create”。有没有办法可以在转发请求时将 URL 更改为 /customers/create ?
此时我无法更改 API 以使“客户”成为“实体”的真正子资源。
RESTEasy (JAX-RS) allows dynamic dispatching via sub-resources. For instance:
POST /customers/create
{"name":"Smith","country":"jp"}
We can have a root resource to handle the path "/customers" with a method annotated with no HTTP method but with @Path("/create"). This method returns a resource that JAX-RS looks at to continue handling the request. However, this resource must handle the "/customers/create" path.
I have an existing situation where different kinds of entities can be created:
POST /customers/create
{"name":"Smith"}
POST /locations/create
{"name":"Chicago"}
I would like to add the ability to create any kind of entity based on an additional property in the body of the request:
POST /entities/create
{"type":"customer","name":"Smith"}
In essence I want to forward the request to the code that handles "POST /customers/create". I can write sub-resource locator that gets called for "POST /entities/create" and returns the Customer resource, but JAX-RS fails to dispatch the request because the Customer resource doesn't handle the path "/entities/create". Is there a way I can change the URL to /customers/create when forwarding the request?
At this point I can't change the API to make "customers" a true subresource of "entities".
发布评论
评论(2)
如果您使用的是实现 JAX-RS 2.0 的 RestEasy 3,那么您可以尝试使用带有
@Provider @PreMatching
注解的ContainerRequestFilter
。在此 Filter 中,您可以调用
ContainerRequestContext#setRequestUri(URI)
方法根据请求的内容更改请求 URI,从而转发到/entities/create 到
/customers/create
或/locations/create
。@PreMatching
注解意味着将在匹配目标资源方法之前调用 Filter,因此您应该能够在此处执行重定向。(您甚至可以替换请求的内容,例如:
{"type":"customer","name":"Smith"}
->{"name":"Smith"}
使用ContainerRequestContext#getInputStream()
和ContainerRequestContext#setInputStream(InputStream)
方法)HTH
泽维尔
If you're using RestEasy 3 which implements JAX-RS 2.0, then you can try to use a
ContainerRequestFilter
annotated with@Provider @PreMatching
.Within this Filter, you can call the
ContainerRequestContext#setRequestUri(URI)
method to change the request URI based on the content of the request, and thus, forward from to/entities/create
to/customers/create
or/locations/create
. The@PreMatching
annotation means that the Filter will be called before the target resource method is matched, so this is where you should be able to perform the redirect.(You may even replace the content of the request, eg:
{"type":"customer","name":"Smith"}
->{"name":"Smith"}
using theContainerRequestContext#getInputStream()
andContainerRequestContext#setInputStream(InputStream)
methods)HTH
Xavier
我怀疑是否有标准的 JAX-RS 方法可以在返回子资源之前更改 URL。但我有一个可能的解决方案来解决你的问题。
像这样定义通用休息资源:
POST /entities/{entityType}
。根据路径参数entityType
,您可以直接决定可以实例化哪些子资源(例如使用静态Map>
来保存实体路径)I doubt there is a standard JAX-RS way to change the URL before returning a subresource. But I have a possible solution to your problem.
Define that Generic Rest Resource like this:
POST /entities/{entityType}
. Depending on the path parameterentityType
you can decide directly what subresouce you can instantiate (e.g using a staticMap<String, Class<?>>
to hold the entity paths)