代码之家  ›  专栏  ›  技术社区  ›  GhostCat

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

  •  2
  • GhostCat  · 技术社区  · 7 年前

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

    @Path("whatever")
    public class WhateverResource {
    
    @POST
    public Response createWhatever(CreateBean bean) { ...
    
    @DELETE
    @Path("/{uuid}")
    public void deleteWhatever(@PathParam("uuid") UUID uuid) { ...
    

    等着去拿,放,头。

    现在我们发现我们需要检查底层功能是否真正启用。一次检查,当失败时,所有操作都将导致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
    

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

    除此之外,这个复制品看起来不太优雅,我想知道是否有一个“更规范”的方法来解决这个问题?

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

    我设想有这样的事情:

    • 一个“基本资源”,它被注册
    • 什么时候 任何 对该资源调用操作时,请求应“委派”,具体取决于该基础功能
    • 或者给一个总是给501的资源
    • 或是真正的资源

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

    1 回复  |  直到 7 年前
        1
  •  2
  •   Paul Samsotha    7 年前

    根据用户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 )

    推荐文章