有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

雅加达。木卫一。WriteAbortedException:写入中止;JAVA木卫一。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)

共 (2) 个答案

  1. # 1 楼答案

    只需实现Serializable

    如果你得到一个^{}像下面这样的

    java.io.NotSerializableException: bean.ProjectAreaBean
    

    然后,它仅仅意味着由异常消息中的完全限定名标识的类(在您的例子中是bean.ProjectAreaBean)没有实现^{}接口,而后面的代码期望它。修复它相对简单,只需让类实现Serializable接口即可

    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。请注意,类的构造函数和初始化块在反序列化过程中不会被调用。如果您希望对序列化和反序列化进行更细粒度的控制,则重写readObject()writeObject()方法。您可以在以下链接中找到具体示例:


    为什么要序列化

    至于为什么您需要担心序列化,这是因为像Tomcat这样的大多数Javaservlet容器都需要类来实现Serializable,只要这些类的实例被存储为^{}的属性。这是因为HttpSession可能需要保存在本地磁盘文件系统上,甚至在servlet容器需要关闭/重新启动或放置在必须同步会话的服务器集群中时需要通过网络传输

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

    另请参见:

  2. # 2 楼答案

    您需要使bean.ProjectAreaBean可序列化