ServletContext
Kiedy kontener serwletu (jak Apache Tomcat ) uruchomi się, wdroży i załaduje wszystkie swoje aplikacje internetowe. Po załadowaniu aplikacji WWW kontener serwletu tworzy go ServletContext
raz i przechowuje w pamięci serwera. Aplikacja internetowa użytkownika web.xml
, a wszystkie zawarte web-fragment.xml
jest analizowany pliki, a każdy <servlet>
, <filter>
a <listener>
znalezione (lub każda klasa opatrzone @WebServlet
, @WebFilter
a @WebListener
odpowiednio) jest tworzony raz i przechowywane w pamięci serwera, jak również. Dla każdego filtrowanego instancji jego init()
metoda jest wywoływana z nowym FilterConfig
.
Kiedy a Servlet
ma wartość <servlet><load-on-startup>
lub @WebServlet(loadOnStartup)
większą niż 0
, wówczas jego init()
metoda jest również wywoływana podczas uruchamiania z nową ServletConfig
. Te serwlety są inicjowane w tej samej kolejności określonej przez tę wartość ( 1
1, 2
2 itd.). Jeśli ta sama wartość jest określona na więcej niż jednej serwletu, to każdy z tych serwletów jest umieszczony na tej samej kolejności, jak w web.xml
, web-fragment.xml
lub @WebServlet
classloading. W przypadku braku wartości „ładuj przy uruchomieniu” init()
metoda zostanie wywołana za każdym razem, gdy żądanie HTTP trafi do tego serwletu po raz pierwszy.
Kiedy kontener serwletu zostanie zakończony wszystkimi opisanymi powyżej krokami inicjalizacji, ServletContextListener#contextInitialized()
zostanie wywołany.
Kiedy zamykają kontener serwletów w dół, to rozładowuje wszystkie aplikacje internetowe, wywołuje destroy()
metodę wszystkich zainicjowanych serwletów i filtrów, a wszystko ServletContext
, Servlet
, Filter
a Listener
przypadki są zaśmiecone. W końcu ServletContextListener#contextDestroyed()
zostanie wywołany.
HttpServletRequest i HttpServletResponse
Kontener serwletu jest podłą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 w produkcji). Gdy klient (np użytkownik z poziomu przeglądarki internetowej, lub programowo przy użyciuURLConnection
) wysyła żądanie HTTP, kontener serwletów tworzy nowy HttpServletRequest
i HttpServletResponse
obiektów i przekazuje je poprzez dowolny zdefiniowany Filter
w łańcuchu, a ostatecznie do Servlet
instancji.
W przypadku filtrów The doFilter()
metoda jest wywoływana. Gdy wywoływany jest kod kontenera serwletu chain.doFilter(request, response)
, żądanie i odpowiedź są kontynuowane do następnego filtru lub trafiają w serwlet, jeśli nie ma już pozostałych filtrów.
W przypadku serwletów The service()
metoda jest wywoływana. Domyślnie ta metoda określa, na podstawie której z doXxx()
metod należy wywołać request.getMethod()
. Jeśli określona metoda jest nieobecna w serwlecie, w odpowiedzi zwracany jest błąd HTTP 405.
Obiekt żądania zapewnia dostęp do wszystkich informacji o żądaniu HTTP, takich jak adres URL, nagłówki, ciąg zapytania i treść. Obiekt odpowiedzi umożliwia kontrolowanie i wysyłanie odpowiedzi HTTP tak, jak chcesz, na przykład, umożliwiając ustawienie nagłówków i treści (zwykle z wygenerowaną treścią HTML z pliku JSP). Po zatwierdzeniu i zakończeniu odpowiedzi HTTP obiekty żądania i odpowiedzi są ponownie przetwarzane i udostępniane do ponownego użycia.
HttpSession
Gdy klient odwiedza aplikację internetową po raz pierwszy i / lub HttpSession
jest uzyskiwany po raz pierwszy request.getSession()
, kontener serwletu tworzy nowy HttpSession
obiekt, generuje długi i unikalny identyfikator (który można uzyskać session.getId()
) i zapisuje go w serwerze pamięć. Kontener serwletu ustawia również Cookie
w Set-Cookie
nagłówku odpowiedzi HTTP JSESSIONID
jako nazwę i unikalny identyfikator sesji jako wartość.
Zgodnie ze specyfikacją plików cookie HTTP (umowa musi być przestrzegana przez każdą przyzwoitą przeglądarkę internetową i serwer), klient (przeglądarka internetowa) musi przesłać ten plik cookie z powrotem w kolejnych żądaniach w Cookie
nagłówku, dopóki plik cookie jest ważny ( tzn. unikalny identyfikator musi odnosić się do sesji, która nie wygasła, a domena i ścieżka są poprawne). Za pomocą wbudowanego monitora ruchu HTTP w przeglądarce możesz sprawdzić, czy plik cookie jest prawidłowy (naciśnij klawisz F12 w przeglądarce Chrome / Firefox 23+ / IE9 + i sprawdź kartę Sieć / Sieć ). Kontener serwletu sprawdzi Cookie
nagłówek każdego przychodzącego żądania HTTP pod kątem obecności pliku cookie z nazwą JSESSIONID
i użyje jego wartości (identyfikatora sesji), aby uzyskać powiązanie HttpSession
z pamięci serwera.
Że HttpSession
pozostaje przy życiu, dopóki nie zostanie bezczynności (nie używany w żądaniu) dłużej niż wartość limitu czasu określonego w <session-timeout>
, w otoczeniu web.xml
. Wartość limitu czasu domyślnie wynosi 30 minut. Tak więc, gdy klient nie odwiedza aplikacji internetowej dłużej niż określony czas, kontener serwletu niszczy sesję. Każde kolejne żądanie, nawet z określonym plikiem cookie, nie będzie już miało dostępu do tej samej sesji; kontener serwletu utworzy nową sesję.
Po stronie klienta plik cookie sesji pozostaje aktywny tak długo, jak długo działa instancja przeglądarki. Tak więc, jeśli klient zamknie instancję przeglądarki (wszystkie karty / okna), sesja zostanie zniszczona 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 HttpSession
utworzenie zupełnie nowego pliku cookie z sesją.
W skrócie
- Trwa
ServletContext
tak długo, jak długo trwa aplikacja internetowa. Jest dzielony między wszystkie żądania we wszystkich sesjach.
- Trwa
HttpSession
tak długo, jak długo klient wchodzi w interakcję z aplikacją internetową z tą samą instancją przeglądarki, a sesja nie przekroczyła limitu czasu po stronie serwera. Jest dzielony między wszystkie żądania w tej samej sesji.
HttpServletRequest
I HttpServletResponse
na żywo od czasu serwlet odbiera żądania HTTP od klienta, aż do całkowitej odpowiedzi (strona internetowa) przyjechał. To jest nie podzielił się gdzie indziej.
- Wszystko
Servlet
, Filter
oraz Listener
przypadki, żyć tak długo jak żyje to aplikacja internetowa. Są one dzielone między wszystkie żądania we wszystkich sesjach.
- Wszelkie
attribute
która jest zdefiniowana w ServletContext
, HttpServletRequest
i HttpSession
będą żyć tak długo, jak obiekt w życiu zapytania. Sam obiekt reprezentuje „zakres” w ramach zarządzania komponentami, takimi jak JSF, CDI, Spring itp. Te struktury przechowują swoje fasole o attribute
określonym zasięgu jako najbliższy pasujący zakres.
Bezpieczeństwo wątków
To powiedziawszy, twoim głównym problemem jest prawdopodobnie bezpieczeństwo wątków . Powinieneś teraz wiedzieć, że serwlety i filtry są wspólne dla wszystkich żądań. To miło, że Java jest wielowątkowa, a różne wątki (czytaj: żądania HTTP) mogą korzystać z tej samej instancji. Byłoby inaczej być zbyt drogie, aby odtworzyć, init()
i destroy()
je dla każdego wniosku.
Należy również zdawać sobie sprawę, że nigdy nie należy przypisywać żadnych danych o zasięgu żądania lub sesji jako zmiennej instancji serwletu lub filtru. Zostanie on udostępniony między wszystkimi innymi żądaniami w innych sesjach. To nie jest bezpieczne dla wątków! 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ż:
PHPSESSID
plikiem cookie, ASP.NET zASP.NET_SessionID
plikiem cookie itp. Dlatego też;jsessionid=xxx
nie jest mile widziane przepisywanie adresów URL za pomocą niektórych ram JSP / Servlet MVC. Upewnij się tylko, że identyfikator sesji nigdy nie jest ujawniany w adresie URL lub w inny sposób na stronach internetowych, aby nieświadomy użytkownik nie został zaatakowany.Sesje
Krótko mówiąc: serwer internetowy wydaje każdemu odwiedzającemu podczas pierwszej wizyty unikalny identyfikator . Odwiedzający musi przynieść ten dowód, aby mógł zostać rozpoznany następnym razem. Ten identyfikator pozwala również serwerowi poprawnie segregować obiekty należące do jednej sesji do drugiej.
Tworzenie instancji serwletu
Jeśli ładowanie przy uruchomieniu jest fałszywe :
Jeśli ładowanie przy uruchomieniu jest prawdziwe :
Gdy znajdzie się w trybie serwisowym i na groove, ten sam serwlet będzie działał na żądanie od wszystkich innych klientów.
Dlaczego nie jest dobrym pomysłem mieć jedną instancję na klienta? Pomyśl o tym: czy zatrudnisz jednego faceta od pizzy na każde zamówienie? Zrób to, a szybko znikniesz z biznesu.
Jednak wiąże się to z niewielkim ryzykiem. Pamiętaj: ten samotny facet ma w kieszeni wszystkie informacje o zamówieniach: więc jeśli nie jesteś ostrożny w kwestii bezpieczeństwa wątków serwletów , może skończyć na złym zamówieniu dla określonego klienta.
źródło
to many requests at this moment. try again later
Sesja w serwletach Java jest taka sama jak sesja w innych językach, takich jak PHP. Jest unikalny dla użytkownika. Serwer może to śledzić na różne sposoby, takie jak pliki cookie, przepisywanie adresów URL itp. W tym artykule w dokumentacji Java wyjaśniono to w kontekście serwletów Java i wskazano, że dokładnie to, jak utrzymywana jest sesja, jest szczegółem implementacji pozostawionym projektantom serwera. Specyfikacja stanowi jedynie, że należy zachować ją jako unikalną dla użytkownika dla wielu połączeń z serwerem. Sprawdź ten artykuł Oracle, aby uzyskać więcej informacji na temat obu pytań.
Edytuj Jest tutaj doskonały samouczek dotyczący pracy z sesją wewnątrz serwletów. A oto rozdział firmy Sun dotyczący serwletów Java, czym są i jak z nich korzystać. Pomiędzy tymi dwoma artykułami powinieneś być w stanie odpowiedzieć na wszystkie pytania.
źródło
ServletContext
obiekt. Ten obiekt ma zero, jeden lub więcej obiektów sesji - zbiór obiektów sesji. Każda sesja jest identyfikowana za pomocą pewnego rodzaju ciągu identyfikującego, co widać w kreskówkach z inną odpowiedzią. Ten identyfikator jest śledzony na kliencie przez cookie lub przepisywanie adresów URL. Każdy obiekt sesji ma własne zmienne.Kiedy kontener serwletu (jak Apache Tomcat) uruchomi się, będzie czytał z pliku web.xml (tylko jeden na aplikację), jeśli coś pójdzie nie tak lub wyświetli błąd w konsoli bocznej kontenera, w przeciwnym razie wdroży i załaduje całą sieć aplikacje przy użyciu pliku web.xml (tak nazwano go jako deskryptor wdrażania).
Podczas fazy tworzenia serwletu instancja serwletu jest gotowa, ale nie może obsłużyć żądania klienta, ponieważ brakuje jej dwóch informacji:
1: informacje kontekstowe
2: informacje o konfiguracji początkowej
Silnik serwletu tworzy obiekt interfejsu servletConfig kapsułkując w nim powyższe brakujące informacje. Wywołuje funkcję silnika serwletu init () serwletu, podając jako argument odwołania do obiektów servletConfig. Po całkowitym uruchomieniu init () serwlet jest gotowy do obsługi żądania klienta.
Q) Ile razy wystąpiła instancja i inicjalizacja serwletu?
A) tylko raz (dla każdego żądania klienta tworzony jest nowy wątek) tylko jedna instancja serwletu obsługuje dowolną liczbę żądań klienta, tj. Po obsłużeniu jednego serwera żądań klienta nie umiera. Oczekuje na inne żądania klienta, tj. Jaki CGI (dla każdego żądania klienta tworzony jest nowy proces), ograniczenie zostaje pokonane przez serwlet (wewnętrzny silnik serwletu tworzy wątek).
P) Jak działa koncepcja sesji?
A) ilekroć wywoływana jest metoda getSession () w obiekcie HttpServletRequest
Krok 1 : obiekt żądania jest oceniany pod kątem identyfikatora sesji przychodzącej.
Krok 2 : jeśli identyfikator nie jest dostępny, tworzony jest nowy obiekt HttpSession, a odpowiadający mu identyfikator sesji (tj. HashTable) identyfikator sesji jest zapisywany w obiekcie odpowiedzi httpservlet, a odwołanie do obiektu HttpSession jest zwracane do serwletu (doGet / doPost) .
Krok 3 : jeśli nie zostanie utworzony nowy dostępny obiekt sesji, identyfikator sesji jest pobierany z żądania, wyszukiwanie odbywa się w kolekcji sesji przy użyciu identyfikatora sesji jako klucza.
Po udanym wyszukiwaniu identyfikator sesji jest zapisywany w HttpServletResponse, a istniejące odwołania do obiektu sesji są zwracane do doGet () lub doPost () UserDefineservlet.
Uwaga:
1) gdy kontrola wychodzi z kodu serwletu do klienta, nie zapomnij, że obiekt sesji jest utrzymywany przez kontener serwletu, tj. Silnik serwletu
2) wielowątkowość jest pozostawiona programistom serwletów do implementacji, tj. Obsłużenia wielu żądań klienta, aby nie zawracać sobie głowy kodem wielowątkowym
Formularz skrócony:
Aplet jest tworzony podczas uruchamiania aplikacji (jest wdrażany w kontenerze serwletu) lub przy pierwszym dostępie (w zależności od ustawienia ładowania przy uruchamianiu), gdy aplet jest tworzony, wywoływana jest metoda init () apletu następnie serwlet (jego jedyna instancja) obsługuje wszystkie żądania (jego metoda service () jest wywoływana przez wiele wątków). Dlatego nie zaleca się synchronizacji i należy unikać zmiennych instancji serwletu, gdy aplikacja nie zostanie wdrożona (kontener serwletu się zatrzyma), wywoływana jest metoda destroy ().
źródło
Sesje - co powiedział Chris Thompson.
Tworzenie instancji - serwlet jest tworzony w momencie, gdy kontener odbierze pierwsze żądanie odwzorowane na serwlet (chyba że serwlet jest skonfigurowany do ładowania przy uruchamianiu z
<load-on-startup>
elementem wweb.xml
). To samo wystąpienie służy do obsługi kolejnych żądań.źródło
Specyfikacja serwletu JSR-315 wyraźnie określa zachowanie kontenera WWW w metodach service (i doGet, doPost, doPut itp.) (2.3.3.1 Problemy z wielowątkowością, strona 9):
źródło
Jak wynika z powyższych wyjaśnień, poprzez wdrożenie modelu SingleThreadModel serwletowi można zapewnić bezpieczeństwo wątków dzięki kontenerowi serwletów. Implementacja kontenera może to zrobić na 2 sposoby:
1) Serializacja żądań (kolejkowanie) do pojedynczej instancji - jest to podobne do serwletu NIE implementującego SingleThreadModel, ALE synchronizującego metody service / doXXX; LUB
2) Tworzenie puli instancji - co jest lepszą opcją i kompromisem między uruchomieniem / inicjalizacją / czasem serwletu w porównaniu z ograniczającymi parametrami (pamięć / czas procesora) środowiska obsługującego serwlet.
źródło
Nie. Serwlety nie są bezpieczne dla wątków
Umożliwia to dostęp do więcej niż jednego wątku na raz
jeśli chcesz, aby serwlet był bezpieczny jako wątek, możesz przejść na
Implement SingleThreadInterface(i)
który jest pustym interfejsem nie mametody
lub możemy przejść do metod synchronizacji
możemy wykonać całą usługę jako zsynchronizowaną za pomocą synchronizacji
słowo kluczowe przed metodą
Przykład::
lub możemy umieścić blok kodu w bloku zsynchronizowanym
Przykład::
Uważam, że synchronizowany blok jest lepszy niż tworzenie całej metody
Zsynchronizowane
źródło