【问题标题】:setAttribute: Non-serializable attribute (Java Object Serialization)setAttribute:不可序列化的属性(Java 对象序列化)
【发布时间】:2009-11-02 16:40:07
【问题描述】:

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

错误是:

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

代码是:

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

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

public List getQuestions() {
    return questions;
}
  • 我们如何制作这个对象 可序列化?
  • 只放 会话中的序列化对象(如 Glassfish 似乎需要)?
  • 会话是否存在风险 在用户之间交换序列化 对象?

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

关于“问题”的更多信息

二传手:

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

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());
}

【问题讨论】:

  • 对于任何有类似问题的人:当您在列表上执行子列表时,您会返回未实现可序列化的 RandomAccessList。所以解决方案是将所有内容添加到像 ArrayList 这样的序列化列表中。

标签: java serialization glassfish


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

    • “问题”从何而来?你在使用 ORM 吗?许多 ORM(如 Hibernate)引入了自己的 Collection 实现。您可能需要解开您的问题并将它们包装到一个普通的 ArrayList 中。另请发布 Question 类的类定义。
    【解决方案3】:

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

    • 实现可序列化
    • 仅具有也可序列化的非静态非瞬态字段

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-28
      • 1970-01-01
      • 2014-05-16
      • 1970-01-01
      • 2013-02-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多