jakarta-ee - java.io.WriteAbortedException : writing aborted; java. io.NotSerializedException

标签 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)

最佳答案

只需实现可序列化

如果您得到 NotSerializableException如下所示,

java.io.NotSerializableException: bean.ProjectAreaBean

那么它只是意味着由异常消息中的完全限定名称标识的类(在您的情况下为 bean.ProjectAreaBean )未实现 Serializable接口(interface),而这是后面的代码所期望的。修复它相对简单,只需让类实现 Serialized 接口(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

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

private transient SomeObject thisWillNotBeSerialized;

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

<小时/>

为什么要序列化?

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

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

另请参阅:

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

相关文章:

jakarta-ee - 一个人应该如何开始学习 Java 企业版?

jakarta-ee - "Exception while loading the app"没有堆栈跟踪

spring - 请求的资源在项目启动 spring mvc 时不可用

java - 如何转换 PNG<->JPEG<->TIFF 图像

java - java中如何从目录中顺序读取文件?

java - 将 blob 转换为 Mp3 但文件无法播放

java - 不同应用服务器上 JNDI 中的自定义资源

java - 在 GAE 中使用 HttpSession 时,我还需要做什么?

maven - 数据库连接 Tomcat Struts2 应用程序

tomcat - 用chef部署war文件后如何重新启动tomcat?