Jersey JAX-RS中的异常处理/资源管理

4

我正在编写一个Jersey RESTful web应用程序,尝试管理共享资源(如数据库会话)。通常我会编写以下代码:

Session session = getSession();
try {
  doWork();
  session.commit();
} finally {
  session.rollback(); // doesn't hurt after commit
  session.release(); // or whatever
}

现在使用Jersey,我有一个资源,如下所示:
@Path("/")
class MyResource {
  @Path("{child}") public Child getChild(...) {
    // how do I manage my session here ???
    return child;
  }
}

问题在于我需要在getChild()中获取session,但是我无法确保在完成工作后正确释放它,因为此时我已经将控制权归还给Web应用程序。
Child也需要访问session,因此我不能将所有工作封装在一个方法中:
class Child {
  @Path("{subchild}") public Subchild getSubchild(...) {
    return new Subchild(session.get(...));
  }
}

我无法在servlet过滤器中包装整个应用程序,因为我需要来自Jersey级别的信息来构建我的会话。现在我可以在MyResource中打开它,使用普通的servlet过滤器确保我始终关闭它,但是我不知道何时回滚以及何时提交会话。我可以使用ExceptionMapper被通知所有异常,但那需要是一个ExceptionMapper,这似乎非常丑陋,将概念性的try/finally分布在三个具有不同生命周期的类之间。
在Jersey中是否有“正确的方法”来进行此类资源管理?如何确保我在资源及其子位置使用后正确关闭例如FileInputStream?
2个回答

0
在REST应用程序中,您不需要向调用传递任何内容。如果您正在getChild中完成工作,那么所有逻辑都应该在那里。根据您的操作,上述内容应该如下所示:
@Path("/{childId}")
class ChildResource {  

    @GET
    public Child getChild(@PathParam("childId") String childId) {    
        //Really, move this into a data access object
        Session session = getSession();
        try {  
            doWork();  
            session.commit();
        } finally {  
            session.rollback(); 
            // doesn't hurt after commit  
            session.release(); 
            // or whatever
        }
        return child;  
    }
}

问题在于Child可以拥有任意数量的子定位器,它们可能也需要访问会话。我将更新问题。 - Martin Probst

-1

使用Spring。绝对不要像那样手动管理资源。这是制造应用程序故障的方法。

*除了可能在测试代码中


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接