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

Jersey/REST: delegating requests to different sub resources without code duplication?

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

@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

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

除此之外,这个复制看起来不太优雅,我想知道是否有解决这个问题的"more canonical"方法?

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

我设想的是:

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

根据用户 Samsotha 的建议,我实现了一个简单的 filter, which is then "connected" via 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。后者将确保该资源中的 any 操作正在通过过滤器!

(可以在任何像样的 Jersey 教程中找到更多详细信息,例如 baeldung 中的教程)