2013-05-13 12 views
5

Wyobraź sobie, że masz filtr, który uruchamia transakcję bazy danych, przetwarza żądanie, a następnie próbuje zatwierdzić transakcję.Czy możesz wykonywać tradycyjne filtrowanie serwletów za pomocą JAX-RS/Jersey?

doFilter(...) { 
    ... 
    transaction.begin(); 
    filterChain.doFilter(request, response); 
    transaction.commit(); 
} 

Korzystanie Jersey, istnieją pewne problemy:

  1. stosując filtr, Jersey Servlet Container zobowiązuje/wypłukuje odpowiedź przed wykonaniem powraca do filtra. Tak więc, jeśli zatwierdzenie nie powiedzie się, nie można zmodyfikować kodu powrotu, aby był niepowodzeniem. Ponadto wyjątki nie zostaną przechwycone przez ExceptionMapper JAX-RS.
  2. Korzystanie z ContainerRequestFilter/ContainerResponseFilter.

    filtr ContainerRequest publicznych (ContainerRequest request) { ... }
    publicznego filtr ContainerResponse (ContainerRequest wniosek, odpowiedź ContainerResponse) { ... }

Pozwala to wyjątki wypłynąć do ExceptionMapper, ale dzieli logikę na 2 osobne metody/interfejsy. Problem polega na tym, że jeśli istnieje wyjątek, który nie jest odwzorowany na odpowiedź, właściwość ContainerResponseFilter nigdy nie jest wywoływana, więc nie można jej wyczyścić.

Jaki jest preferowany sposób postępowania w środowisku JAX-RS? Czy istnieje sposób na skonfigurowanie płukania odpowiedzi lub czy istnieje klasa lub interfejs, z którego przeglądam?

+0

To, co opisujesz, jest powszechnie znane jako "wzorzec otwartej sesji" (anty). Zobacz [to pytanie SO] (http://stackoverflow.com/q/1103363/131929) do dyskusji. Zwróć się także do JBoss (Hibernate/Seam), aby uzyskać więcej dyskusji, np. https://community.jboss.org/docs/DOC-13954 –

+0

Istnieje pewna debata na temat tego, czym dokładnie jest "widok", ale jest to po prostu aplikacja REST. Metody zasobów jax-rs są warstwą usługi i bezpośrednio wykorzystują funkcję utrwalania. Obiekt odpowiedzi jest wynikiem wywołania usługi. Próbuję uniknąć zarządzania transakcjami w każdej metodzie, a odpowiedź jest albo czymś podobnym do filtra, albo podłączam do przechwytywania CDI (którego chciałbym uniknąć w tym momencie w projekcie, jeśli mogę). – Shaun

Odpowiedz

3

Sprawdzam to również dla aplikacji JAX-RS/RESTEasy. Dwie opcje Zastanawiałem się przed przeczytaniem tego pytanie:

  1. Napisz e ExceptionMapper<Throwable> (lub ExceptionMapper<DaoException> ze zwyczajem DaoException) i obsługiwać go tam lub w ContainerResponseFilter że dostanie wykonanego ze względu na ExceptionMapper<?> obsługi wszystkich wyjątków.
  2. Przed transaction.begin() sprawdź bieżący stan transakcji i w razie potrzeby wycofaj.

Występują problemy z obiema opcjami.

  1. znajdę ExceptionMapper<Throwable> zbyt szerokie, natomiast ExceptionMapper<DaoException> może przegapić jakiś inny wyjątek, ponownie pozostawiając transakcja nie czyszczone.
  2. Wycofywanie transakcji przy następnym żądaniu może zająć dużo czasu, prawdopodobnie powodując problemy z blokowaniem innych transakcji.

Więc po przeczytaniu swoje pytanie, mam obecnie myśli:

  • Korzystanie ContainerRequestFilter do rozpoczęcia transakcji (w połączeniu z budową @NameBinding adnotacji).
  • Korzystanie z ContainerResponseFilter do zatwierdzania transakcji (jeśli metoda zasobów jeszcze jej nie zamknęła).
  • Korzystanie z Filter, aby upewnić się, że transakcja została zamknięta, a jeśli nie, wycofaj ją.
+0

Jak masz na myśli "ExceptionMapper too broad"? Jeśli po prostu sprawdzisz sesję dla aktywnej transakcji w ExceptionMapper , możesz być pewien, że coś poszło nie tak i wycofać. Jeśli nie ma aktywnej transakcji, nie rób nic. Problem, który widzę, to jeśli transaction.commit() nie powiedzie się w ContainerResponseFilter, obiekt odpowiedzi musiałby zostać zmieniony. Nie jesteś pewien, co się stanie, jeśli wyjątek zostanie zgłoszony w ContainerResponseFilter, czy zostanie on przechwycony przez ExceptionMapper? – joscarsson

+0

Zbyt szeroki w tym sensie, że możesz również mieć 'ExceptionMapper . Który "ExceptionMapper " obsłuży wyjątek? Najpierw dla "SpecificException", a potem dla 'Throwable'? A może ten ostatni połknie "SpecificException"? – drvdijk