Обработка исключений / управление ресурсами в Джерси JAX-RS - PullRequest
3 голосов
/ 04 июня 2009

Я пытаюсь управлять ресурсом (например, в сеансе базы данных) при программировании веб-приложения RESTful на Джерси. Обычно я написал бы код, подобный этому:

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 (), но я не могу убедиться, что правильно выполнил его после завершения работы, поскольку я уже вернул контроль веб-приложению.

Ребенок также нуждается в доступе к сеансу, поэтому я не могу инкапсулировать всю работу в один метод:

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

Я не могу обернуть все приложение в фильтр сервлета, поскольку мне нужна информация с уровня Джерси для построения моего сеанса. Теперь я могу просто открыть его в MyResource, использовать обычный фильтр сервлетов, чтобы всегда закрывать его, но тогда я не знаю, когда откатываться, а когда фиксировать сеанс. Я мог бы использовать ExceptionMapper, чтобы получать уведомления обо всех исключениях, но это должен был бы быть ExceptionMapper, и это просто кажется очень уродливым, с концептуальной попыткой / окончательно распределить по трем классам с различным временем жизни и т. Д.

Есть ли "правильный путь" для такого управления ресурсами на Джерси? Как мне убедиться, что я правильно закрыл, например, FileInputStream после ресурса и его sub-locatos использовали его?

Ответы [ 2 ]

0 голосов
/ 09 августа 2011

Использовать пружину . Никогда * не управляйте своими ресурсами вручную. Это рецепт для сломанных приложений.

* за исключением возможно в тестовом коде

0 голосов
/ 10 июня 2009

В приложении 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;  
    }
}
...