Jersey で RESTful Web アプリケーションをプログラミングしているときに、競合するリソース (データベース セッションなど) を管理しようとしています。通常、私は次のようなコードを書きます。
Session session = getSession();
try {
doWork();
session.commit();
} finally {
session.rollback(); // doesn't hurt after commit
session.release(); // or whatever
}
ジャージーを使用すると、次のようなリソースがあります。
@Path("/")
class MyResource {
@Path("{child}") public Child getChild(...) {
// how do I manage my session here ???
return child;
}
}
問題は、getChild() でセッションを取得する必要があることですが、Web アプリケーションに制御を戻してしまっているため、作業が完了した後にセッションを適切に解放できるかどうかを確認できません。
子もセッションにアクセスする必要があるため、すべての作業を 1 つのメソッドにカプセル化することはできません。
class Child {
@Path("{subchild}") public Subchild getSubchild(...) {
return new Subchild(session.get(...));
}
}
セッションを構築するためにジャージー レベルからの情報が必要なため、アプリケーション全体をサーブレット フィルターでラップすることはできません。これで、MyResource で開くことができます。通常のサーブレット フィルターを使用して、常に閉じるようにしますが、ロールバックするタイミングとセッションをコミットするタイミングがわかりません。ExceptionMapper を使用してすべての例外を通知することもできますが、これは ExceptionMapper である必要があり、概念的な try/finally が異なるライフタイムを持つ 3 つのクラスに分散されているなど、非常に醜いように思えます。
Jersey でこの種のリソース管理を行う「正しい方法」はありますか? リソースとそのサブロカトがそれを使用した後、たとえば FileInputStream を適切に閉じるにはどうすればよいですか?