package pl.japila; import java.io.IOException; import javax.servlet.AsyncContext; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(urlPatterns = "/AsyncServlet", asyncSupported = true) public class AsyncServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { AsyncContext asyncCtx = request.getAsyncContext(); response.getWriter().printf("<h2>AsyncContext: %s</h2>", asyncCtx); } }Niech to będzie początkiem mojego eksperymentu naukowego, którego obiektem jesteś...Ty! :-)
08 maja 2012
Asynchroniczne przetwarzanie w Servlet 3.0
Napisał:
Unknown
Poniższy servlet kończy się wyjątkiem - java.lang.IllegalStateException - na linii 18, w której dostaję się do javax.servlet.AsyncContext. Dlaczego?
Subskrybuj:
Komentarze do posta (Atom)
Cytując JavaDoc: "getAsyncContext() Throws: IllegalStateException - if this request has not been put into asynchronous mode" - musisz najpierw zawołać startAsync().
OdpowiedzUsuńPrzed, po czy może w ramach metody?! Jakiej? Gdzie miałbym zawołać startAsync()?
OdpowiedzUsuńDokumentacja wydaje się jasna: najpierw musisz zawołać startAsync() w servlecie (która to metoda zwraca AsyncContext) a potem możesz wołać getAsyncContext() dowoli, niekoniecznie w servlecie, uzyskując ten sam obiekt typu AsyncContext. Zerknij na mój wpis o Servlet 3.0.
OdpowiedzUsuńJasna, jasna. Teraz przypominam sobie Twój wpis, ale jego zawartość trochę mnie przeraziła i nie pamiętam, czy dotarłem do samego końca.
OdpowiedzUsuńA dlaczego wołasz request.startAsync(request, response); w DownloadServletHandler.handleRequest?
Bo muszę :-). Specyfikacja wymaga, abym zawołał startAsync() wewnątrz servletu jeśli chcę obsłużyć żądanie asynchronicznie. W przeciwnym wypadku w chwili powrotu z doService() kontener zamknie połączenie i uzna je za obsłużone. Zobacz moje odpowiedzi na SO: [1] i [2].
OdpowiedzUsuńMusisz startAsync(), ale nie(koniecznie) wariant z dwoma parametrami wejściowymi - startAsync(req, res). Pytam, dlaczego użyłeś wariantu dwuargumentowego? I tylko nie pisz mi, że "bo muszę", bo to za będzie za mało :-)
OdpowiedzUsuńPrawdę mówiąc nie wiem - jeśli używasz oryginalnego obiektu żądania i odpowiedzi, wersja bezargumentowa wystarczy. Wersja dwuargumentowa ma zastosowanie jeśli chcesz dodatkowo opakować jeden lub oba obiekty - nie wiem, jakie ma to zastosowanie praktyczne w tym przypadku. Innymi słowy mój kod mógłby być nieco prostszy.
OdpowiedzUsuńGotcha! :-) Czułem, że do tego dojdziemy. Eksperyment się powiódł. Dziękuję za udział! Nagroda jest Twoja.
OdpowiedzUsuńPowiem szczerze, że bardziej niż nagroda (uścisk dłoni odbiorę na Confiturze ;-)) interesuje mnie czego chciałeś dowieźć? Innymi słowy - czego spodziewałeś się po komentarzach czytelników?
OdpowiedzUsuńNiczego nie dowodziłem, a jedynie uczyłem się w doborowym towarzystwie :) Coś mi mówi, że krótkie wpisy mogą być większą inspiracją do rozmów/wymiany doświadczeń niż dłuższe, a i prościej się je pisze. Ostatecznie chciałbym poświęcić więcej czasu na nagrania/skrinkasty. Właśnie przygotowuję scenariusz.
OdpowiedzUsuń