Ответ 1
Просто реализуйте Serializable
Если вы получаете NotSerializableException
как NotSerializableException
ниже,
java.io.NotSerializableException: bean.ProjectAreaBean
тогда это просто означает, что класс, идентифицируемый полностью определенным именем в сообщении об исключении (которое в вашем случае является bean.ProjectAreaBean
), не реализует интерфейс Serializable
то время как это ожидается кодом, стоящим за ним. Исправить это относительно просто, просто позвольте классу реализовать интерфейс Serializable
.
package bean;
import java.io.Serializable;
public class ProjectAreaBean implements Serializable {
private static final long serialVersionUID = 1L;
// ...
}
Поле serialVersionUID
не является обязательным, но настоятельно рекомендуется, поскольку оно поддерживает двоичную совместимость между различными версиями класса и сериализованными представлениями его экземпляров. Поэтому, когда вы позже добавите новое сериализуемое поле в класс, вам нужно будет изменить поле serialVersionUID
(обычно достаточно просто увеличить его на 1), чтобы предотвратить проблемы при десериализации экземпляра более старой версии класса. Среды IDE, такие как Eclipse, также предлагают возможность (пере) генерировать значение serialVersionUID
которое в основном является хешем, вычисляемым на основе всех полей.
Смотрите также:
- Управляемый компонент JSF вызывает исключение java.io.NotSerializableException во время развертывания Tomcat
- Внедрение несериализуемого bean-объекта области применения в качестве управляемого свойства сериализуемого bean-компонента области действия в кластере
- Что такое serialVersionUID и почему я должен его использовать?
Пометить несериализуемые поля как transient
Если ваш класс Serializable
содержит, в свою очередь, поле/свойство, ссылающееся на экземпляр другого класса, который абсолютно нельзя сделать Serializable
(обычно это представляют ресурсы, такие как InputStream
, Connection
и т.д.), Вам необходимо пометить его как transient
. Таким образом, он будет пропущен во время сериализации класса.
private transient SomeObject thisWillNotBeSerialized;
Вы должны понимать, что после десериализации это поле всегда будет null
. Обратите внимание, что конструктор класса и блоки инициализации не вызываются во время десериализации. Если вы хотите иметь более точный контроль над сериализацией и десериализацией, переопределите readObject()
и writeObject()
. Вы можете найти конкретные примеры в ссылках ниже:
- Запретить сериализацию дерева компонентов для определенных частей приложения
- Как сделать постоянные файлы cookie с помощью DefaultHttpClient в Android?
Почему сериализация?
Что касается того, почему вам нужно беспокоиться о сериализации, то это потому, что большинству контейнеров сервлетов Java, таких как Tomcat, требуются классы для реализации Serializable
всякий раз, когда экземпляры этих классов хранятся в качестве атрибута HttpSession
. Это связано с тем, что HttpSession
возможно, необходимо сохранить в локальной файловой системе на диске или даже передать по сети, когда сервлет-контейнер необходимо отключить/перезапустить или он помещается в кластер серверов, где сеанс должен быть синхронизирован.
Чтобы иметь возможность сохранять объекты Java в файловой системе локального диска или передавать их по сети, их необходимо сначала преобразовать в поток байтов (в основном: byte[]
или InputStream
), и это возможно только в том случае, если класс за объектом реализует Serializable
. Сам интерфейс Serializable
ничего не делает, это просто маркерный интерфейс. Код только делает instanceof Serializable
проверки атрибута сеанса, чтобы действовать соответственно.