【问题标题】:RESTEasy JAX-RS dynamic dispatching other than subresourcesRESTEasy JAX-RS 动态调度(子资源除外)
【发布时间】:2011-09-28 22:05:25
【问题描述】:

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 以使“客户”成为“实体”的真正子资源。

【问题讨论】:

    标签: jax-rs resteasy


    【解决方案1】:

    如果您使用的是实现 JAX-RS 2.0 的 RestEasy 3,那么您可以尝试使用带有 @Provider @PreMatching 注释的 ContainerRequestFilter

    在这个Filter中,你可以调用ContainerRequestContext#setRequestUri(URI)方法根据请求的内容改变请求的URI,从而从/entities/create转发到/customers/create/locations/create@PreMatching 注释意味着过滤器将在目标资源方法匹配之前被调用,所以这是你应该能够执行重定向的地方。

    (您甚至可以替换请求的内容,例如: {"type":"customer","name":"Smith"} -> {"name":"Smith"} 使用 ContainerRequestContext#getInputStream()ContainerRequestContext#setInputStream(InputStream) 方法)

    HTH 泽维尔

    【讨论】:

    • 不要忘记使用资源 URI。即setRequestUri(new Uri("/path/to/other"))
    【解决方案2】:

    我怀疑在返回子资源之前是否有标准的 JAX-RS 方法来更改 URL。但我对你的问题有一个可能的解决方案。

    像这样定义通用休息资源:POST /entities/{entityType}。根据路径参数entityType,您可以直接决定可以实例化哪些子资源(例如,使用静态Map<String, Class<?>> 来保存实体路径)

    【讨论】:

      猜你喜欢
      • 2016-10-02
      • 1970-01-01
      • 1970-01-01
      • 2014-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-08
      相关资源
      最近更新 更多