2009-06-04 7 views
3

J'essaie de gérer une ressource contenue (comme dans: session de base de données) lors de la programmation d'une application Web RESTful dans Jersey. En général, j'écrire du code comme ceci:Gestion des exceptions/gestion des ressources dans Jersey JAX-RS

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

Maintenant avec Jersey, j'ai une ressource comme ceci:

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

Le problème est que je dois acquérir la session getChild(), mais Je ne peux pas m'assurer que je le relâche correctement après que le travail ait été fait puisque j'ai déjà rendu le contrôle à l'application Web.

enfant a besoin d'accéder à la session, donc je ne peux pas résumer tout le travail dans une méthode:

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

Je ne peux pas envelopper toute l'application dans un filtre de servlet comme je l'ai besoin d'informations du Jersey niveau pour construire ma session. Maintenant, je pourrais juste l'ouvrir dans MyResource, utiliser un filtre de servlet standard pour m'assurer de toujours le fermer, mais je ne sais pas quand revenir en arrière et quand valider la session. Je pourrais utiliser un ExceptionMapper pour être averti de toutes les exceptions, mais cela devrait être un ExceptionMapper, et cela semble si extrêmement moche, avec le conceptuel/finalement réparti sur trois classes avec des durées de vie différentes et ainsi de suite.

Existe-t-il une «bonne façon» de faire ce genre de gestion des ressources à Jersey? Comment est-ce que je m'assurerais de fermer correctement par ex. un FileInputStream après une ressource et ses sous-locatos l'ont utilisé?

Répondre

0

Dans une application REST, vous n'êtes pas obligé de transmettre quoi que ce soit à un appel. Si vous faites le travail dans getChild, c'est là que devrait se trouver toute la logique. Deviner ce que vous faites, ce qui précède devrait se lire:

@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

Le problème est que l'enfant peut avoir des sous-localisateurs arbitraires qui pourraient avoir besoin d'un accès à la session, aussi. Je vais mettre à jour la question. –

0

Use Spring. Jamais * gérer vos ressources manuellement comme ça. C'est une recette pour les applications cassées.

* sauf peut-être dans le code de test