Jak mogę się upewnić, że moja aplikacja WWW serwletów Java jest bezpieczna dla wątków? Co muszę zrobić ze względu na zmienne sesji, zmienne statyczne klasy lub cokolwiek innego, co może być problemem z bezpieczeństwem wątków?W języku Java, w jaki sposób mogę się upewnić, że moja aplikacja internetowa jest bezpieczna dla wątków?
Odpowiedz
Fakt: Jest tylko 1 instancja serwletu w webapp-tych dożywotni. Powstaje na starcie aplikacji webapp i zostaje zniszczony po zamknięciu aplikacji internetowej. Zobacz także this answer dla interpretacji zgrubnej.
W ten sposób została udostępniona wszystkim żądaniom (wątkom). Jeśli przypiszesz dane żądania lub dane o ograniczonej sesji jako instancję (lub jeszcze gorzej, jako zmienną static
), to z pewnością nie jest ona bezpieczna dla wątków, ponieważ została następnie udostępniona wszystkim aplikacjom (wątkom) od wszystkich użytkowników (sesji) w całym serwisie. Wystarczy przypisać je jako zmienne lokalne metody, aby zachować ich bezpieczeństwo. Więc:
public class MyServlet 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.
}
}
To w zasadzie wszystko, co trzeba wziąć pod uwagę przy opracowywaniu serwletów z threadsafety w umyśle.
Następnie istnieją atrybuty sesji (HttpSession
), które mogą być współużytkowane przez wiele żądań od tego samego użytkownika, ale w rzeczywistości nie trzeba się martwić synchronizowaniem dostępu do sesji. Zwykle umieszczasz tam tylko dane specyficzne dla użytkownika, takie jak zalogowany użytkownik, preferencje użytkownika, koszyk zakupów itp. Musisz tylko upewnić się, że nie wprowadzasz danych o czystym zasięgu w zakresie sesji. Zostałaby odzwierciedlona w wielu oknach/zakładkach przeglądarki wewnątrz tej samej sesji.
Następnie są atrybuty aplikacji (ServletContext
), które są udostępniane wszystkim użytkownikom na całym świecie, ale zwykle dodaje się tam tylko stałe i inne dane statyczne, takie jak konfiguracja webapp, fabryka DAO, zawartość listy rozwijanej itp.To wszystko można przy okazji zrobić z ServletContextListener
, patrz także podstawowy przykład na stronie this answer. Trzeba tylko upewnić się, że nie umieszczasz czystych danych o zakresie żądania lub sesji w zakresie aplikacji.
Masz na myśli w kontekście, w przeciwieństwie do innych aplikacji java? Naprawdę nie ma dużej różnicy. Każde żądanie do serwletu powoduje, że kontener wydaje nowy wątek do obsługi, więc zmienne instancji w serwlecie muszą być wątkowo bezpieczne. Lepiej radzić sobie z całym bizem ze zmiennymi lokalnymi w metodach doGet/doPost(). Jest jedna myśl, którą mogę wymyślić. W przypadku zmiennych sesji może się zdarzyć, że użytkownik ma otwarte dwa okna przeglądarki, oba kierujące do aplikacji. W takim przypadku należy również zwrócić uwagę na bezpieczeństwo nici z zakresem sesji.
Wow, to naładowane pytanie.
Mówiąc prościej, należy się upewnić, że dostęp do wszystkich współdzielonych danych jest dokładnie zsynchronizowany. Np. Możesz chcieć zsynchronizować dostęp do zmiennej statycznej za pomocą muteksu lub funkcji zsynchronizowanej.
Należy pamiętać, że w przypadku transakcji atomowych, które modyfikują wiele współdzielonych zasobów w tym samym czasie, konieczna może być synchronizacja na wyższych poziomach.
Projektowanie aplikacji współbieżnej nie jest proste i nie ma magicznej kuli (niestety). Gorąco polecam książkę "Java Concurrency in Practice", aby uzyskać więcej informacji na temat pisania bezpiecznego kodu współbieżnego.
- nie używaj zmiennych instancji serwletów i filtrów
- nie używać zmiennych statycznych
- read this article on session thread safety
- myśleć
- 1. Używanie Java 6, w systemie Linux, w jaki sposób mogę się upewnić, że korzystam z gniazda ipv4?
- 2. W przypadku PDO, w jaki sposób mogę się upewnić, że instrukcja UPDATE zakończyła się pomyślnie?
- 3. Dowiedz się, ile wątków obsługuje moja aplikacja?
- 4. W języku Java, czy muszę zadeklarować, że moja kolekcja jest zsynchronizowana, jeśli jest tylko do odczytu?
- 5. Jak mogę się upewnić, że użytkownik jest zalogowany tylko raz?
- 6. W Perlu, w jaki sposób mogę się upewnić, że ciąg odpowiada poprawnej dacie?
- 7. Czy metoda executeUpdate w Javie jest bezpieczna dla wątków?
- 8. Czy usługa Azure CloudTable jest bezpieczna dla wątków?
- 9. Jak mogę się upewnić, że kodowanie pliku jest prawidłowe?
- 10. W jaki sposób moja aplikacja jednowątkowa Rails obsługuje żądania równoczesne?
- 11. W jaki sposób można upewnić się, że plik wykonywalny jest otwierany za pomocą innego pliku wykonywalnego?
- 12. Jak upewnić się, że zmienna jest obiektem?
- 13. Aplikacja internetowa Java Spring uruchamia się powoli w trybie debugowania
- 14. Klasa bezpieczna dla wątków w języku Java za pomocą zsynchronizowanych bloków
- 15. Jaki jest najbardziej pythonic sposób, aby upewnić się, że wszystkie elementy listy są różne?
- 16. Czy budowa obiektu funkcji statycznej zakresu jest bezpieczna dla wątków?
- 17. Jak mogę się upewnić, że główny wątek kończy się po zakończeniu wszystkich pozostałych wątków?
- 18. Jak mogę się upewnić, że funkcja strtol() powiodła się?
- 19. Aplikacja tekstowa w języku Java
- 20. Czy java jest bezpieczna?
- 21. Jaki jest najlepszy sposób, aby upewnić się, że działa tylko jedna instancja programu Perl?
- 22. Czy istnieje lista klas bezpiecznych dla wątków w języku Java?
- 23. Aplikacja internetowa w Delphi
- 24. Asystent zgodności programów myśli, że moja aplikacja jest instalatorem
- 25. komercyjna aplikacja internetowa PHP -
- 26. Jak upewnić się, że kod jest ponownie używany poprawnie?
- 27. Jak udowodnić, że lista kontrolna nie jest bezpieczna dla wątków za pomocą testu?
- 28. Jak mogę się upewnić, że przeciągnięty element zachowuje szerokość oryginału?
- 29. Jak upewnić się, że Rails API jest zabezpieczony przed CSRF?
- 30. Jak wykryć, że moja aplikacja straciła ostrość w Qt?
Jedno pytanie dotyczące "jednego serwletu w życiu aplikacji internetowej" - Myślałem, że to obiekt połączony, więc tam * może * być więcej niż jeden według uznania serwletu w zależności od obciążenia. Czy to nie prawda? – duffymo
Tylko jeśli implementuje (zgodnie z serwletem 2.4 przestarzałe) 'SingleThreadModel'. – BalusC
@BalusC: Dziękuję bardzo Panie, ta odpowiedź pomogła mi w końcu. Usunąłem moje pytanie i przegłosowałem twoją odpowiedź. Nie ma nikogo takiego jak ty w Javie. Jeszcze raz dziękuję za milion. –