Jak działają serwlety? Tworzenie instancji, sesje, współdzielone zmienne i wielowątkowość

Załóżmy, że mam serwer, który zawiera wiele serwletów. Dla przekazywania informacji pomiędzy tymi serwletami ustawiam zmienne sesji I instancji.

Teraz, jeśli 2 lub więcej użytkowników wyśle żądanie do tego serwera, to co się stanie ze zmiennymi sesji? Czy wszystkie będą wspólne dla wszystkich użytkowników, czy będą różne dla każdego użytkownika. Jeśli są różne, to w jaki sposób serwer był w stanie odróżnić różnych użytkowników?

Jeszcze jedno podobne pytanie, jeśli są n użytkownicy uzyskujący dostęp do określonego servletu, wtedy ten servlet zostanie utworzony tylko przy pierwszym wejściu do niego pierwszego użytkownika, czy też zostanie utworzony dla wszystkich użytkowników osobno? Innymi słowy, co dzieje się ze zmiennymi instancji?

Author: Taryn, 2010-06-24

7 answers

ServletContext

Po uruchomieniu kontenera serwletów (jak Apache Tomcat), zostanie on wdrożony i załadowany wszystkie swoje aplikacje internetowe. Po załadowaniu aplikacji webowej kontener servlet tworzy ServletContext raz i przechowuje go w pamięci serwera. Plik web.xml aplikacji internetowej jest przetwarzany, a każdy <servlet>, <filter> i <listener> znalezione (lub każda klasa opatrzona adnotacją @WebServlet, @WebFilter i @WebListener odpowiednio) jest tworzona raz i przechowywana w pamięci serwera. Dla każdego instantiated filter, jego metoda init() jest wywoływana z nowym FilterConfig.

Kiedy kontener servletów się wyłączy, rozładuje wszystkie aplikacje webowe, wywoła metodę destroy() wszystkich zainicjowanych serwletów i filtrów, i wszystkie ServletContext, Servlet, Filter i Listener instancje są zniszczone.

Gdy Servlet ma wartość <servlet><load-on-startup> lub @WebServlet(loadOnStartup) większą niż 0, jej metoda init() jest również wywoływana podczas uruchamiania z nowym ServletConfig. Serwlety te są inicjowane w tym samym kolejność określona tą wartością(1 - > 1st, 2 - > 2nd, itd.). Jeśli ta sama wartość jest podana dla więcej niż jednego servletu, to każdy z tych servletów jest ładowany w kolejności, w jakiej występuje w klasach web.xml lub @WebServlet. W przypadku braku wartości "load-on-startup", metoda init() zostanie wywołana za każdym razem, gdy żądanie HTTP trafi do serwletu po raz pierwszy.

W związku z tym, że nie jest to możliwe, nie jest to konieczne.]}

Kontener servlet jest dołączony do serwera WWW, który nasłuchuje żądań HTTP na określonym numerze portu (port 8080 jest zwykle używany podczas programowania, a port 80 podczas produkcji). Gdy klient (użytkownik z przeglądarką internetową) wysyła żądanie HTTP, kontener servlet tworzy nowe HttpServletRequest oraz HttpServletResponse obiekty i przekazuje je przez dowolny zdefiniowany łańcuch Filter i ostatecznie instancję Servlet.

W przypadku filtrów wywoływana jest metoda doFilter(). Gdy jego kod wywołuje chain.doFilter(request, response), żądanie i odpowiedź przejdź do następnego filtra lub naciśnij servlet, jeśli nie ma pozostałych filtrów.

W przypadku servletów wywoływana jest metoda service(). Domyślnie ta metoda określa, która z metod doXxx() ma zostać wywołana na podstawie request.getMethod(). Jeżeli określona metoda nie występuje w serwlecie, wtedy w odpowiedzi zwracany jest błąd HTTP 405.

Obiekt request zapewnia dostęp do wszystkich informacji o żądaniu HTTP, takich jak jego nagłówki i treść. Obiekt response zapewnia możliwość kontrolowania i wysyłania odpowiedzi HTTP w dowolny sposób, na przykład, umożliwiając ustawienie nagłówków i treści (zwykle z wygenerowaną zawartością HTML z pliku JSP). Po zatwierdzeniu i zakończeniu odpowiedzi HTTP zarówno obiekty request, jak i response są poddawane recyklingowi i przeznaczone do ponownego użycia.

HttpSession

Gdy klient odwiedza webapp po raz pierwszy i / lub HttpSession otrzymuje się po raz pierwszy za pomocą request.getSession(), kontener servleta tworzy nowy obiekt HttpSession, generuje długi i unikalny identyfikator (który można uzyskać przez session.getId()) i przechowuje go w pamięci serwera. Pojemnik servlet ustawia również Cookie w nagłówku Set-Cookie odpowiedzi HTTP z JSESSIONID jako nazwą i unikalnym identyfikatorem sesji jako wartością.

Pliki cookies (tzw. "ciasteczka") stanowią dane informatyczne, w szczególności pliki tekstowe, które przechowywane są w urządzeniu końcowym Użytkownika Serwisu i przeznaczone są do korzystania ze stron internetowych Serwisu. pliki cookie w kolejnych żądaniach w nagłówku Cookie tak długo, jak plik cookie jest ważny (tzn. unikalny identyfikator musi odnosić się do niewykorzystanej sesji, a Domena i ścieżka są poprawne). Korzystając z wbudowanego w przeglądarkę monitora ruchu HTTP, możesz sprawdzić, czy plik cookie jest prawidłowy(naciśnij klawisz F12 w Chrome / Firefox 23+ / IE9+ i sprawdź kartę Net / Network ). Kontener serwleta sprawdza nagłówek Cookie każdego przychodzącego żądania HTTP pod kątem obecności pliku cookie o nazwie JSESSIONID i użyj jej wartości (ID sesji), aby pobrać skojarzoną HttpSession z pamięci serwera.

HttpSession pozostaje żywy, dopóki nie zostanie użyty dłużej niż wartość timeout określona w <session-timeout>, ustawieniu w web.xml. Wartość timeout domyślnie wynosi 30 minut. Tak więc, gdy klient nie odwiedza aplikacji sieci web dłużej niż określony czas, kontener serwleta traci sesję. Każde kolejne żądanie, nawet z podanym ciasteczkiem, nie będzie miało już dostępu do tej samej sesji; kontener servlet utworzy nową sesję.

Po stronie klienta plik cookie sesji pozostaje żywy tak długo, jak działa instancja przeglądarki. Jeśli więc klient zamknie instancję przeglądarki (Wszystkie zakładki / okna), wtedy sesja zostanie usunięta po stronie klienta. W nowej instancji przeglądarki plik cookie powiązany z sesją nie istniałby, więc nie byłby już wysyłany. Powoduje to utworzenie całkowicie nowego HTTPSession, Z rozpoczęciem całkowicie nowego pliku cookie sesji używany.

W skrócie

  • ServletContext żyje tak długo, jak żyje aplikacja internetowa. Jest współdzielony pomiędzy wszystkie żądania w wszystkie sesje.
  • the HttpSession żyje tak długo, jak klient wchodzi w interakcję z aplikacją internetową za pomocą tej samej instancji przeglądarki, a sesja nie została przerwana po stronie serwera. Jest on dzielony pomiędzy wszystkie żądania w tej samej sesji.
  • the HttpServletRequest and HttpServletResponse live from the time servlet otrzymuje żądanie HTTP od klienta, dopóki nie nadejdzie pełna odpowiedź (strona internetowa). Jest to Nie dzielone gdzie indziej.
  • wszystkie Servlet, Filter i Listener instancje żyją tak długo, jak długo żyje aplikacja internetowa. Są one dzielone pomiędzy wszystkie żądania w wszystkie sesje.
  • Dowolna attribute zdefiniowana w ServletContext, HttpServletRequest i HttpSession będzie żył tak długo, jak długo przedmiot, o którym mowa, będzie żył. Sam obiekt reprezentuje "zakres" w zarządzaniu frameworki takie jak JSF, CDI, Spring itp. Framework ten przechowuje swój zakres jako attribute najbliższego mu zakresu.

Zabezpieczenie Gwintu

To powiedziawszy, Twoim głównym zmartwieniem jest prawdopodobnie bezpieczeństwo wątku. Powinieneś teraz wiedzieć, że serwlety i filtry są wspólne dla wszystkich żądań. To jest fajna rzecz Javy, jest ona wielowątkowa i różne wątki (Czytaj: żądania HTTP) mogą korzystać z tej samej instancji. W przeciwnym razie byłoby zbyt drogie, aby odtworzyć, init() i destroy() je dla każdego pojedynczego żądania.

Powinieneś również zdać sobie sprawę, że nie powinieneś nigdy przypisywać żadnych danych o zasięgu żądania lub sesji jako zmienną instancji serwletu lub filtra. Zostanie on udostępniony wszystkim innym żądaniom w innych sesjach. To Nie thread-safe! Poniższy przykład ilustruje to:

public class ExampleServlet extends HttpServlet {

    private Object thisIsNOTThreadSafe;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Object thisIsThreadSafe;

        thisIsNOTThreadSafe = request.getParameter("foo"); // BAD!! Shared among all requests!
        thisIsThreadSafe = request.getParameter("foo"); // OK, this is thread safe.
    } 
}

Zobacz też:

 1646
Author: BalusC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-05 14:25:29

Sesje

Tutaj wpisz opis obrazkaTutaj wpisz opis obrazka

W skrócie: serwer WWW wysyła unikalny identyfikator do każdego odwiedzającegopodczas jego pierwszej wizyty. Odwiedzający musi przynieść ten dowód, żeby go rozpoznano następnym razem. Ten identyfikator pozwala również serwerowi na poprawne oddzielenie obiektów należących do jednej sesji od obiektów należących do innej.

Servlet Instantiation

If load-on-startup is false :

Tutaj wpisz opis obrazkaTutaj wpisz opis obrazka

Jeśli load-on-startup is true :

Tutaj wpisz opis obrazkaTutaj wpisz opis obrazka

Gdy jest w trybie serwisowym i w groove, ten sam servlet będzie działał na żądania od wszystkich innych klientów.

Tutaj wpisz opis obrazka

Dlaczego nie jest dobrym pomysłem posiadanie jednej instancji na klienta? Pomyśl o tym: czy zatrudnisz jednego faceta od pizzy do każdego zamówienia, które przyszło? Zrób to, a w mgnieniu oka wylecisz z interesu.

Wiąże się to jednak z niewielkim ryzykiem. Pamiętaj: ten samotny facet trzyma wszystkie informacje o zamówieniu w jego kieszeni: więc jeśli nie jesteś ostrożny z zabezpieczeniem wątku na serwletach , może skończyć się wydaniem niewłaściwego zamówienia pewnemu klientowi.
 403
Author: Jops,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-25 15:47:00

Sesja w serwletach Java jest taka sama jak sesja w innych językach, takich jak PHP. Jest unikalny dla użytkownika. Serwer może śledzić go na różne sposoby, takie jak pliki cookie, przepisywanie adresów url itp. Ten artykuł Java doc wyjaśnia to w kontekście serwletów Java i wskazuje, że dokładnie jak utrzymywana jest sesja, szczegóły implementacji pozostawione są projektantom serwera. Specyfikacja przewiduje tylko, że musi być utrzymywana jako unikalna dla użytkownika w wielu połączenia z serwerem. Sprawdź Ten artykuł Oracle, aby uzyskać więcej informacji na temat obu pytań.

Edit jest tu doskonały tutorial Jak pracować z sesją wewnątrz servletów. I tutaj{[2] } jest rozdział Sun o Serwletach Javy, czym są i jak ich używać. Pomiędzy tymi dwoma artykułami powinieneś być w stanie odpowiedzieć na wszystkie Twoje pytania.

 40
Author: Chris Thompson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-17 05:59:35

Gdy servletcontainer (jak Apache Tomcat) się uruchomi, odczyta z sieci.plik xml (tylko jeden na aplikację) jeśli coś pójdzie nie tak lub pojawi się błąd w konsoli bocznej kontenera, w przeciwnym razie wdroży i załaduje wszystkie aplikacje webowe za pomocą web.xml (tak nazwałem go deskryptorem wdrożenia).

Podczas fazy tworzenia instancji servleta, servletInstance jest gotowe, ale nie może obsłużyć żądania klienta, ponieważ brakuje mu dwóch Informacji:
1: kontekst informacje
2: Informacje o konfiguracji początkowej

Servlet engine tworzy obiekt interfejsu servletConfig hermetyzując do niego powyższe brakujące informacje silnik servleta wywołuje INIT () servleta przez dodanie referencji do obiektu servletConfig jako argumentu. Po całkowitym wykonaniu INIT() servlet jest gotowy do obsługi żądania klienta.

Q) w czasie życia servleta ile razy zachodzi instancjacja i initaializacja ??

A) tylko raz (dla każdego klienta poproś o utworzenie nowego wątku) tylko jedna instancja serwletu obsługuje dowolną liczbę żądań klienta, tzn. po serwowaniu jednego serwera żądań klienta nie umiera. Czeka na inne prośby klientów czyli co CGI (na każde żądanie klienta tworzony jest nowy proces) ogranicza się do servleta (wewnętrznie servlet engine tworzy wątek).

Q) jak działa koncepcja sesji?

A)gdy getSession () jest wywołane w obiekcie HttpServletRequest

Krok 1 : Prośba obiekt jest ewalauowany pod kątem ID sesji przychodzącej.

Krok 2:Jeśli ID nie jest dostępny, tworzony jest nowy obiekt HttpSession i generowany jest odpowiadający mu identyfikator sesji (tj. HashTable) identyfikator sesji jest zapisywany w obiekcie odpowiedzi httpservlet, a odniesienie do obiektu HttpSession jest zwracane do servleta (doGet/doPost).

Krok 3: Jeśli ID dostępny nowy obiekt sesji nie jest tworzony, identyfikator sesji jest pobierany z wyszukiwania obiektu żądania w zbieranie sesji za pomocą identyfikatora sesji jako klucza.

Po pomyślnym przeszukiwaniu identyfikator sesji jest zapisywany w HttpServletResponse, a istniejące odniesienia do obiektów sesji są zwracane do doGet() lub doPost () UserDefineservlet.

Uwaga:

1) gdy kontrola odchodzi z kodu servleta do klienta nie zapomnij, że obiekt sesji jest przechowywany przez servletcontainer ie, servletengine

2) wielowątkowość jest pozostawiona ludziom Servlet devlopers do implementacji ie., obsługa wielu żądań klienta nie ma potrzeby przejmowania się kodem wielowątkowym

W formie skróconej:

Servlet jest tworzony podczas uruchamiania aplikacji (jest wdrażany w kontenerze servlet) lub gdy jest po raz pierwszy dostępny (w zależności od ustawienia load-on-startup) gdy Servlet jest utworzony, metoda INIT () servleta jest wywoływana następnie servlet (jego jedyna instancja) obsługuje wszystkie żądania (jego metoda service () jest wywoływana przez wiele wątków). Dlatego tak jest. nie zaleca się w nim żadnej synchronizacji i należy unikać zmiennych instancji servletu gdy aplikacja nie zostanie uruchomiona (kontener servleta zatrzymuje się), wywoływana jest metoda destroy ().

 31
Author: Ajay Takur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-23 08:56:37

Sesje - co powiedział Chris Thompson.

Instantiation - servlet jest tworzony, gdy kontener otrzyma pierwsze żądanie odwzorowane na servlet (chyba że servlet jest skonfigurowany do ładowania przy starcie z elementem <load-on-startup> w web.xml). Ta sama instancja jest używana do obsługi kolejnych żądań.

 20
Author: Lauri Lehtinen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-24 00:27:46

Specyfikacja Servleta JSR-315 jasno definiuje zachowanie kontenera sieciowego w usłudze (oraz doGet, doPost, doPut itp.) metody (2.3.3.1 zagadnienia wielowątkowe, Strona 9):

Kontener servlet może wysyłać równoczesne żądania za pośrednictwem usługi metoda serwletu. Aby obsłużyć żądania, programista Servleta musi zawierać odpowiednie przepisy dotyczące jednoczesnego przetwarzania z wieloma wątki w metodzie service.

Chociaż nie jest zalecane, alternatywą dla dewelopera jest zaimplementuj interfejs SingleThreadModel, który wymaga kontenera aby zagwarantować, że istnieje tylko jeden wątek żądania na raz w metoda serwisowa. Pojemnik servlet może spełnić ten wymóg poprzez serializowanie żądań na serwletach lub poprzez utrzymywanie puli serwletów przypadki. Jeśli servlet jest częścią aplikacji webowej, która została oznaczony jako distributable, kontener może utrzymywać pulę serwletów instancje w każdy JVM, że aplikacja jest rozproszona.

Dla serwletów nie implementujących interfejsu SingleThreadModel, jeśli metoda serwisowa (lub metody takie jak doGet czy doPost, które są wysyłane do metody service klasy abstrakcyjnej HttpServlet) został zdefiniowany za pomocą słowa kluczowego synchronized, servlet container nie można użyć metody puli wystąpień, ale musi serializować żądania przez to. Zdecydowanie zaleca się, aby programiści nie synchronizowali serwis metoda (lub metody do niej wysyłane) w tych okoliczności ze względu na szkodliwy wpływ na wydajność

 13
Author: tharindu_DG,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-26 08:07:57

Nie. serwlety są Nie bezpieczne dla wątków

Is umożliwia dostęp do więcej niż jednego wątku na raz

Jeśli chcesz, aby Servlet jako wątek Bezpieczny ., U can go for

Implement SingleThreadInterface(i) który jest pustym interfejsem nie ma

Metody

Lub możemy przejść do metod synchronizacji

Możemy zrobić całą metodę usługi jako zsynchronizowaną za pomocą zsynchronizowanej

Keword przed metoda

Przykład::

public Synchronized class service(ServletRequest request,ServletResponse response)throws ServletException,IOException

Lub możemy umieścić blok kodu w zsynchronizowanym bloku

Przykład::

Synchronized(Object)

{

----Instructions-----

}

Uważam, że synchronizowany blok jest lepszy niż cała Metoda

Zsynchronizowane

 0
Author: Ved Prakash,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-14 15:32:40