我正在尝试在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()中获取会话,但我无法确保在完成工作后正确地释放它,因为我已经将控制权交给了Web应用程序。
Child也需要访问会话,因此我无法将所有工作封装在一个方法中:
class Child {
@Path("{subchild}") public Subchild getSubchild(...) {
return new Subchild(session.get(...));
}
}
我无法将整个应用程序包装在servlet Filter中,因为我需要来自Jersey级别的信息来构建我的会话。现在我可以在MyResource中打开它,使用常规的servlet过滤器来确保我总是关闭它,但后来我不知道何时回滚以及何时提交会话。我可以使用ExceptionMapper来通知所有异常,但这需要是一个ExceptionMapper,这看起来非常难看,概念上的try / finally分布在三个具有不同生命周期的类上等等。
泽西岛有没有“正确的方法”来进行这种资源管理?我如何确保正确关闭,例如资源及其子locatos使用后的FileInputStream?
答案 0 :(得分: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;
}
}
答案 1 :(得分:0)
Use Spring。从来没有像这样手动管理您的资源。这是破坏应用程序的秘诀。
*除了测试代码中的