Чому HttpServlet реалізує Serializable?


77

На моє розуміння Servlet, Servlet буде створений екземпляром Container, його init()метод буде викликаний один раз, і сервлет буде жити як одиночний, поки JVM не вимкнеться.

Я не очікую, що мій сервлет буде серіалізований, оскільки він буде створений новим, коли сервер додатків відновиться або запуститься нормально. Сервлет не повинен містити жодних членів сесії, тому не має сенсу його записувати на диск і повторно створювати. Чи є для цього практичне використання?

Мене турбує те, що я вклав туди деякі поля, які не можна серіалізувати, і тоді мій додаток загадково вийде з ладу у виробничому середовищі, де відбуватиметься інший тип реплікації сеансу.


Відповіді:


59

Технічно я вважаю, що контейнеру сервлету дозволено "пасивувати" об'єкт сервлета на диск, подібним чином, яким можуть бути сеанси EJB. Тож ви правильно ставите запитання, чи ваш додаток вийде з ладу через несеризуються поля.

На практиці я ніколи не чув про те, щоб контейнер робив це, тож це насправді лише застарілий багаж із поганих старих часів на початку J2EE. Я б про це не хвилювався.


1
Але кому потрібно пасивувати сервлет, коли він повинен бути безпечним для потоків і не мати стану розмови?
Амір Пашазаде

1
Це робить так, щоб сервери кластера не виходили з ладу і мапували
Dev

2
Помилка @dev стосується несеріалізованих атрибутів сеансу, а НЕ про будь-яку серіалізацію сервлетів.
Аренд проти Рейнерсдорфа,

Це може бути викликано наявністю <distributable />в web.xml.
Архімед Траяно

11

HttpServlet повинен серіалізуватися на диск і пережити перезапуск контейнера сервлетів. Наприклад, tomcat дозволяє встановити прапор, який дозволяє вижити такого роду. Наступним варіантом є передача за допомогою JNDI. Це не сміття, воно використовується лише в екстремальних випадках.


Чи єдиний правильний спосіб встановити поля, які не можна серіалізувати? Це так жахливо. :(
Трейказ

1

Google, схоже, припускає, що це було зроблено для того, щоб автори контейнерів мали можливість, якщо вони цього хочуть.

Ви праві, що сервлет не повинен містити жодних членів сесії, насправді я б подумав, що ви хотіли б якомога менше стану. Якщо ви зберігаєте все в Session або ServletConfig, я думаю, ви зможете пережити серіалізацію.


2
Ну, сеанс набагато частіше буде серіалізованим, ніж сервлет, тому зберігання його там не пом'якшить проблему.
skaffman

1
@matt b: стурбованість не стільки специфічним для сеансу станом, скільки власними залежностями сервлета (наприклад, об'єкти сервісного рівня)
Ендрю Свон

0

Подібно до того, як об'єкти Session серіалізуються для виживання кеш-пам’яті для тих сервлетконтейнерів, що дають опцію кластера, може існувати опція для контейнера перенести екземпляр Сервлета також до іншого вузла кластера ?? Я тут просто здогадуюсь


-3

Серіалізація використовується як інтерфейс маркера для атрибутів сеансу в розподіленому середовищі.

SRV.7.7.2 Розподілене середовище (JSR-154)

У додатку, позначеному як розповсюджуваний , усі запити, які є частиною сеансу, повинні оброблятися одночасно однією віртуальною машиною Java (“JVM”). Контейнер повинен мати можливість обробляти всі об'єкти, розміщені у екземплярах класу HttpSession, використовуючи методи setAttribute або putValue належним чином. Для задоволення цих умов накладаються такі обмеження:

  • Контейнер повинен приймати об'єкти, що реалізують інтерфейс, що серіалізується .
  • Міграція сесій здійснюватиметься спеціально для контейнерів.

Контейнер розподіленого сервлета повинен викидати IllegalArgumentException для об'єктів, де контейнер не може підтримувати механізм, необхідний для міграції сеансу, що їх зберігає .

Контейнер розподіленого сервлета повинен підтримувати механізм, необхідний для міграції об'єктів, що реалізують серіалізацію .

(...)

Постачальник контейнерів може забезпечити масштабованість та якість таких функцій обслуговування, як балансування навантаження та відмовостійкість, маючи можливість переміщувати об'єкт сеансу та його вміст із будь-якого активного вузла розподіленої системи в інший вузол системи. Якщо розподілені контейнери зберігаються або переносять сеанси для забезпечення якісних функцій обслуговування, вони не обмежуються використанням власного механізму серіалізації JVM для серіалізації HttpSessions та їх атрибутів. Розробникам не гарантується, що контейнери викликатимуть методи readObject і writeObject в атрибутах сеансу, якщо вони їх реалізують, але гарантують, що серіалізаційне закриття їх атрибутів буде збережено .


3
Це оманлива відповідь. Екземпляр сервлета зазвичай не зберігається в сеансі.
BalusC
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.