jakarta-ee - java.io.WriteAbortedException : writing aborted; java. io.NotSerializableException 异常

标签 jakarta-ee tomcat java-io catalina notserializableexception

Tomcat 出现这种错误的原因是什么?

SEVERE: Exception loading sessions from persistent storage
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException:
   bean.ProjectAreaBean
 at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1333)
 at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
 at java.util.ArrayList.readObject(ArrayList.java:593)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(
    DelegatingMethodAccessorImpl.java:25)

最佳答案

只需实现Serializable

如果你得到一个 NotSerializableException如下所示,

java.io.NotSerializableException: bean.ProjectAreaBean

那么它只是意味着由异常消息中的完全限定名称标识的类(在您的情况下为 bean.ProjectAreaBean)未实现 Serializable接口(interface),而它是后面的代码所期望的。修复起来比较简单,让类实现Serializable接口(interface)即可。

package bean;

import java.io.Serializable;

public class ProjectAreaBean implements Serializable {
    private static final long serialVersionUID = 1L;

    // ...
}

serialVersionUID 字段不是必需的,但强烈建议这样做,因为它可以保持类的不同版本及其实例​​的序列化表示之间的二进制兼容性。因此,当您稍后向该类添加一个新的可序列化字段时,您需要更改 serialVersionUID 字段(通常只需将其递增 1 就足够了)以防止在反序列化一个实例的过程中出现问题该类的旧版本。 Eclipse 等 IDE 还提供了一个选项来(重新)生成 serialVersionUID 值,该值基本上是基于所有字段计算的哈希值。

另见:


标记不可序列化的字段transient

如果您的 Serializable 类依次包含一个字段/属性,该字段/属性引用另一个类的实例,而这绝对不能成为Serializable(通常,这些代表资源,例如InputStreamConnection 等),那么您需要将其标记为transient。这样它将在类的序列化期间被跳过。

private transient SomeObject thisWillNotBeSerialized;

您需要了解,在反序列化之后,该字段将始终变为 null。请注意,类的构造函数和初始化 block 在反序列化过程中不会被调用。如果您想对序列化和反序列化进行更细粒度的控制,请覆盖 readObject()writeObject() 方法。您可以在以下链接中找到具体示例:


为什么要序列化?

至于为什么您需要担心序列化,这是因为大多数 Java servlet 容器(如 Tomcat)需要类在存储这些类的实例时实现 Serializable作为 HttpSession 的属性.这是因为 HttpSession 可能需要保存在本地磁盘文件系统上,甚至在 servlet 容器需要关闭/重新启动或被放置在 session 发生的服务器集群中时甚至通过网络传输同步。

为了能够将 Java 对象保存在本地磁盘文件系统或通过网络传输它们,必须先将它们转换为字节流(基本上:byte[]InputStream),只有对象背后的类实现了 Serializable 才有可能。 Serializable 接口(interface)本身并没有真正做任何事情,它只是一个 marker interface。 .后面的代码只是对 session 属性执行 instanceof Serializable 检查以采取相应行动。

另见:

关于jakarta-ee - java.io.WriteAbortedException : writing aborted; java. io.NotSerializableException 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2294551/

相关文章:

java - 在 eclipse 中使用 java.io 库,以便 FileInputStream 可以读取 dat 文件

java io - 正则表达式不起作用 - 为什么

java - 哪里可以找到com.sun.enterprise.security.auth.realm.JDBCRealm的来源?

java.lang.NumberFormatException : Infinite or NaN at java. 数学.BigDecimal

java - 从开发到生产集成 Java Web 应用程序

Tomcat https POST 数据

java - servlet 是否共享同一个 servletoutputstream 对象?

java - 无法编译 JSP : The type java. util.Map$Entry 的类无法解析。它是从所需的 .class 文件间接引用的

java - 通过 File.deleteOnExit 清理排队等待删除的文件

java - request.getScheme() 正在返回 http 而不是在 java 中返回 https