Почему HttpServlet реализует Serializable?

В моем понимании сервлета экземпляр сервлета будет создан Контейнером, его метод init() будет вызываться один раз, и сервлет будет жить как синглтон, пока JVM не выключится.

Я не ожидаю, что мой сервлет будет сериализован, поскольку он будет создан новым, когда сервер приложений восстановится или запустится нормально. Сервлет не должен содержать членов, зависящих от сеанса, поэтому нет смысла записывать его на диск и повторно создавать его. Есть ли в этом практическая польза?

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

Аналогично: Цель сериализации в веб-приложении

Basil Bourque 28.05.2017 02:07
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
78
1
13 377
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

Технически я считаю, что контейнеру сервлета разрешено «пассивировать» объект сервлета на диск, аналогично тому, как это могут быть сессионные компоненты EJB. Итак, вы правы, задавая вопрос, откажет ли ваше приложение из-за несериализуемых полей.

На практике я никогда не слышал, чтобы контейнер делал это, так что на самом деле это просто унаследованный багаж из плохих старых времен раннего J2EE. Я бы не стал об этом беспокоиться.

Но кому нужно пассивировать сервлет, если он должен быть потокобезопасным и не иметь состояния разговора?

Amir Pashazadeh 27.01.2013 14:56

Это сделано для того, чтобы серверы кластера не выходили из строя и отображали сеанс в случае сбоев, аналогичная ошибка проверяет это, issues.apache.org/bugzilla/show_bug.cgi?id=30809

Dev 10.01.2014 14:35

@dev ошибка касается несериализуемых атрибутов сеанса, а НЕ какой-либо сериализации сервлетов.

Arend v. Reinersdorff 12.01.2017 01:39

Это может быть вызвано наличием <distributable /> в web.xml.

Archimedes Trajano 06.05.2017 05:45

Google, кажется, предполагает, что это было сделано для того, чтобы авторы контейнеров могли иметь возможность, если они этого захотят.

Вы правы, что сервлет не должен содержать членов, зависящих от сеанса, на самом деле я думаю, вам нужно как можно меньше состояния. Если вы сохраните все в Session или ServletConfig, я думаю, вы сможете пережить сериализацию.

Что ж, сеанс гораздо более вероятно будет сериализован, чем сервлет, поэтому его сохранение там не решит проблему.

skaffman 07.10.2008 22:40

@matt b: проблема не столько в состоянии, зависящем от сеанса, сколько в собственных зависимостях сервлета (например, объекты уровня сервиса)

Andrew Swan 07.04.2009 08:38

Точно так же, как объекты сеанса сериализуются, чтобы выжить в кэше для тех контейнеров сервлетов, которые предоставляют параметр кластера, у контейнера может быть возможность передать экземпляр сервлета также на другой узел кластера ?? Я здесь просто догадываюсь

HttpServlet должен быть сериализован на диск и пережить перезапуск контейнера сервлетов. Например, tomcat позволяет вам установить флаг, который разрешает такое выживание. Следующий вариант - передача по JNDI. Это не фигня, используется только в крайних случаях.

Является ли JNDI единственно правильным способом установки полей, которые нельзя сериализовать? Это так ужасно. :(

Trejkaz 21.06.2017 07:47

Serializable используется как маркер интерфейс для атрибутов сеанса в распределенной среде.

SRV.7.7.2 Distributed Environments (JSR-154)

Within an application marked as distributable, all requests that are part of a session must be handled by one Java Virtual Machine (“JVM”) at a time. The container must be able to handle all objects placed into instances of the HttpSession class using the setAttribute or putValue methods appropriately. The following restrictions are imposed to meet these conditions:

  • The container must accept objects that implement the Serializable interface.
  • Migration of sessions will be handled by container-specific facilities.

The distributed servlet container must throw an IllegalArgumentException for objects where the container cannot support the mechanism necessary for migration of the session storing them.

The distributed servlet container must support the mechanism necessary for migrating objects that implement Serializable.

(...)

The Container Provider can ensure scalability and quality of service features like load-balancing and failover by having the ability to move a session object, and its contents, from any active node of the distributed system to a different node of the system. If distributed containers persist or migrate sessions to provide quality of service features, they are not restricted to using the native JVM Serialization mechanism for serializing HttpSessions and their attributes. Developers are not guaranteed that containers will call readObject and writeObject methods on session attributes if they implement them, but are guaranteed that the Serializable closure of their attributes will be preserved.

Это вводящий в заблуждение ответ. Экземпляр сервлета обычно не сохраняется в сеансе.

BalusC 06.11.2011 00:11

Другие вопросы по теме