2009-06-04 5 views
3

Ich versuche, eine konkurrierende Ressource (wie in: Datenbanksitzung) zu verwalten, während ich eine RESTful-Webanwendung in Jersey programmiere. Normalerweise würde ich Code wie folgt schreiben:Ausnahmebehandlung/Ressourcenverwaltung in Jersey JAX-RS

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

Jetzt mit Jersey, habe ich eine Ressource wie folgt aus:

@Path("/") 
class MyResource { 
    @Path("{child}") public Child getChild(...) { 
    // how do I manage my session here ??? 
    return child; 
    } 
} 

Das Problem ist, dass ich die Sitzung in getChild() zu erwerben, aber Ich kann nicht sicherstellen, dass ich es nach getaner Arbeit ordnungsgemäß freigegeben habe, da ich dann bereits die Kontrolle an die Webanwendung zurückgegeben habe.

Kind benötigt Zugriff auf die Sitzung als gut, so kann ich nicht die ganze Arbeit in einer Methode kapseln:

class Child { 
    @Path("{subchild}") public Subchild getSubchild(...) { 
    return new Subchild(session.get(...)); 
    } 
} 

Ich kann nicht die gesamte Anwendung in einem Servlet-Filter umhüllt, wie ich Informationen aus der Jersey-Ebene brauche um meine Sitzung aufzubauen. Jetzt könnte ich es einfach in MyResource öffnen, benutze einen regulären Servlet-Filter, um sicherzustellen, dass ich es immer schließe, aber dann weiß ich nicht, wann ich ein Rollback durchführen soll und wann ich die Sitzung festschreiben soll. Ich könnte einen ExceptionMapper verwenden, um über alle Exceptions benachrichtigt zu werden, aber das müsste ein ExceptionMapper sein, und das scheint nur so extrem hässlich zu sein, mit dem konzeptionellen try/finally verteilt auf drei Klassen mit unterschiedlichen Lebensdauern und so weiter.

Gibt es einen "richtigen Weg", um diese Art der Ressourcenverwaltung in Jersey zu tun? Wie würde ich sicherstellen, dass ich z.B. ein FileInputStream nach einer Ressource und ihre Sub-Locatos haben es benutzt?

Antwort

0

In einer REST-Anwendung müssen Sie nichts an einen Anruf übergeben. Wenn Sie die Arbeit in getChild erledigen, sollte das die ganze Logik sein. Raten Sie, was Sie tun, sollte das obige lesen:

@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; 
    } 
} 
+0

Das Problem ist, dass Kind willkürliche Unter Locators haben kann, den Zugriff auf die Sitzung benötigen könnte auch. Ich werde die Frage aktualisieren. –

0

Use Spring. Verwalte niemals deine Ressourcen manuell so. Es ist ein Rezept für gebrochene Anwendungen.

* außer vielleicht in Testcode

Verwandte Themen