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?
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.
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ą.
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
andHttpServletResponse
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
iListener
instancje żyją tak długo, jak długo żyje aplikacja internetowa. Są one dzielone pomiędzy wszystkie żądania w wszystkie sesje. - Dowolna
attribute
zdefiniowana wServletContext
,HttpServletRequest
iHttpSession
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 jakoattribute
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ż:
- Jaka jest różnica między JSF, Servletem a JSP?
- najlepsze rozwiązanie do zarządzania sesjami w Javie
- różnica między / i / * we wzorcu URL mapowania serwleta
- doGet i doPost w Serwletach
- Servlet wydaje się obsługiwać wiele jednoczesnych żądań przeglądarki synchronicznie
- dlaczego serwlety nie są bezpieczne dla wątków?
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
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 :
Jeśli load-on-startup is true :
Gdy jest w trybie serwisowym i w groove, ten sam servlet będzie działał na żądania od wszystkich innych klientów.
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.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.
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 ().
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ń.
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ść
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
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