Jersey / REST:将请求委派给不同的子资源,而无需代码重复?

时间:2018-08-01 12:03:42

标签: java jersey jax-rs

我们创建了一个资源,例如:

@Path("whatever")
public class WhateverResource {

@POST
public Response createWhatever(CreateBean bean) { ...

@DELETE
@Path("/{uuid}")
public void deleteWhatever(@PathParam("uuid") UUID uuid) { ...

以此类推,例如GET,PUT和HEAD。

现在,我们认为我们需要检查底层功能是否真正启用。一次检查,如果检查失败,则所有操作都只会导致501。

我的第一个想法是复制现有资源,例如:

@Path("whatever")
public class WhateverResourceIsntAvailable {

@POST
public Response createWhatever(CreateBean bean) { 
  throw 501

@DELETE
@Path("/{uuid}")
public void deleteWhatever(@PathParam("uuid") UUID uuid) { 
  throw 501

因此,两个资源都指定了完全相同的操作。导致我们无法(轻松)在需要注册资源的时间点调用该检查的问题。

除此之外,这种复制看起来并不十分优雅,我想知道是否存在“更规范”的解决方案?

编辑:另一个选择是将检查添加到现有资源中,并添加到每个资源中,但这意味着:对每个操作进行检查。添加新操作时很容易忘记。

我设想具有以下特征:

  • 已注册的“基础资源”
  • 在该资源上调用 any 操作时,应“委托”该请求,具体取决于该基础功能
  • 要么总是只给出501的资源
  • 或指向执行实际工作的“实际”资源

理想情况下,无需重复检查代码或重复操作端点规范。

1 个答案:

答案 0 :(得分:2)

根据用户Samsotha的建议,我实现了一个简单的filter,然后通过name binding“连接”,例如:

@Path("whatever")
@MyNewFilter
public class WhateverResource {
...

并且:

@MyNewFilter
public class MyNewFilterImpl implements ContainerRequestFilter {
  @Override
  public void filter(ContainerRequestContext context) {      
    if (... feature is enabled )) {
        ... nothing to do
    } else {
        context.abortWith(
                Response.status(Response.Status.NOT_IMPLEMENTED).entity("not implemented").build());
    }
}

此方法的主要优点在于,可以注释单个操作,也可以注释整个资源,例如我的WhateverResource。后者将确保该资源中的任何操作正在通过过滤器!

(进一步的细节可以在任何不错的泽西教程中找到,例如baeldung上的教程)