setAttribute:不可序列化的属性(Java 对象序列化)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1662348/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 18:51:58  来源:igfitidea点击:

setAttribute: Non-serializable attribute (Java Object Serialization)

javaserializationglassfish

提问by Omnipresent

We just switched to Glassfish V2. We are now getting errors when setting a session attribute.

我们刚刚切换到 Glassfish V2。我们现在在设置会话属性时遇到错误。

Error is:

错误是:

java.lang.IllegalArgumentException: PWC2788: setAttribute: Non-serializable attribute

Code is:

代码是:

getRequest().getSession().setAttribute("questionsForUser", getQuestions());

getQuestions() is just a simple getter which is inside an abstract class named 'Parent Action'....so to make getQuestions() a serialized object does my class need to implement serializable?:

getQuestions() 只是一个简单的 getter,它位于一个名为“Parent Action”的抽象类中……所以要使 getQuestions() 成为序列化对象,我的类是否需要实现可序列化?:

public List getQuestions() {
    return questions;
}
  • How can we make this object serializable?
  • is it a good practice to only put serialized object in the session (as Glassfish appears to be requiring)?
  • Are there risks of sessions being swapped between users with serialized objects?
  • 我们如何使这个对象可序列化?
  • 只在会话中放置序列化对象是一个好习惯(因为 Glassfish 似乎需要)?
  • 是否存在会话在具有序列化对象的用户之间交换的风险?

Edit: I am using ORM (iBatis)

编辑:我正在使用 ORM (iBatis)

More Information about "Questions"

有关“问题”的更多信息

setter:

二传手:

public void setQuestions(List questions) {
    this.questions = questions;
}

setter is called inside this method. this method calls the iBatis mappings.

setter 在这个方法中被调用。此方法调用 iBatis 映射。

public void prepareQuestions()
{        
setExamIfaceDAO((SecurityExamIfaceDAO)ApplicationInitializer.getApplicationContext().getBean("securityExamIfaceDAO"));
    String userRole = questionsBasedOnUserRole();
    int questionsToBeShown = 0;
    if (userRole.equalsIgnoreCase("C"))
        questionsToBeShown = 15;
    else if (userRole.equalsIgnoreCase("U"))
        questionsToBeShown = 10;
    List local_questions = getExamIfaceDAO().getSecurityQuestions(userRole);
    Collections.shuffle(local_questions);
    if (local_questions.size()>=questionsToBeShown)
        setQuestions(local_questions.subList(0, questionsToBeShown));
    getRequest().getSession().setAttribute("questionsForUser", getQuestions());
}

采纳答案by Andy

You can make the object serializable by using a serializable List implementation and making sure that the objects in the list are also serializable.

您可以通过使用可序列化的 List 实现并确保列表中的对象也是可序列化的来使对象可序列化。

Yes -- it is good practice to only put serializable objects in the session since this will allow your application to be run on a server with multiple nodes. Even if you don't care about this at the moment it might be useful in future.

是的——只在会话中放置可序列化的对象是一种很好的做法,因为这将允许您的应用程序在具有多个节点的服务器上运行。即使您目前不关心这一点,它也可能在将来有用。

The servlet container should ensure that sessions are not swapped between users. Making objects stored in the session serializable allows the container to 'distribute' the session state across multiple nodes in a cluster, allowing the user who owns the session to have requests serviced by any node.

servlet 容器应确保会话不会在用户之间交换。使存储在会话中的对象可序列化允许容器在集群中的多个节点之间“分发”会话状态,从而允许拥有会话的用户让任何节点为请求提供服务。

回答by Licky Lindsay

It is requiring them to be serializable because the servlet spec says that they have to be if the "distributable" tag is in web.xml. The spec assumes servlet engines will replicate sessions across services using serialization.

它要求它们是可序列化的,因为 servlet 规范说如果“distributable”标签在 web.xml 中,它们必须是可序列化的。该规范假设 servlet 引擎将使用序列化跨服务复制会话。

The only way to make it be serializable is to... use an implementation of List that is serializable! You must have written your own custom List class, since all the implementations in the JDK are serializable that I know of. Either that or the objects in the list are not serializable.

使其可序列化的唯一方法是...使用可序列化的 List 实现!您一定已经编写了自己的自定义 List 类,因为据我所知,JDK 中的所有实现都是可序列化的。要么是列表中的对象,要么是不可序列化的。

Or you could just remove the "distributable" if you don't care if your sessions get replicated across multiple servers or not.

或者,如果您不关心会话是否在多个服务器之间复制,则可以删除“可分发”。

回答by BalusC

What type of objects does the List contain? I.e. what's the generic type of the List? Is it List<String> or List<Question> wherein Question is a homegrown javabean class? If the latter is the case, you need to let it implement java.io.Serializable. That's basically all. You're also required by the javabean specification to do so.

List 包含什么类型的对象?即列表的泛型类型是什么?它是 List<String> 还是 List<Question> 其中 Question 是一个自产的 javabean 类?如果是后者,则需要让它实现java.io.Serializable。这基本上就是全部。javabean 规范也要求您这样做。

回答by Ramon

All the JDK collections are serializable if their elements are serializable. My guess is its the List elementsthat are not serializable, not the List object itself. To (over-)simplify, for an object to be serializable it must:

如果所有 JDK 集合的元素都是可序列化的,那么它们都是可序列化的。我的猜测是它是不可序列化的 List元素,而不是 List 对象本身。为了(过度)简化,对于要序列化的对象,它必须:

  • Implement Serializable
  • Only have non-static non-transient fields that are also serializable
  • 实现可序列化
  • 只有非静态非瞬态字段也是可序列化的