【问题标题】:Cannot serialize an Enum to GWT无法将枚举序列化为 GWT
【发布时间】:2011-11-08 20:45:52
【问题描述】:

如果 Enum 实现了 java.io.Serializable,我无法将其序列化为 GWT。它将 GWT 编译成功,但在运行时,我得到了可怕的:

类型“com....security..AdminPrivilege”不可分配给“com.google.gwt.user.client.rpc.IsSerializable”并且没有自定义字段序列化程序。出于安全目的,此类型将不被序列化。:实例 = 登录到控制台

如果我实现 com.google.gwt.user.client.rpc.IsSerializable 它可以编译并运行良好。我试图避免 IsSerializable,因为这个 Enum 持久存在于我们的数据库中,并且在非 GWT servlet 中被引用。我不想引入 GWT 依赖项,即使对于那个单一的类也是如此。

我已在此处阅读了有关此主题的大部分讨论。我有:

  1. 添加了一个 serialVersionUid(这应该不是必需的)
  2. 添加了一个无参数构造函数(但这是一个枚举,所以它必须是私有的 - 我怀疑这可能是问题所在)
  3. 添加了一个可调用的 RPC 方法,该方法返回 Enum 并将 Enum 的 Set 作为输入参数(尝试将此 Enum 加入白名单) -

对于所有其他枚举,我生成了一个实现 IsSerializable 的 GWT 版本。但是这个新的 Enum 生成起来太复杂了,我需要 GWT 代码中 Enum 中的方法。

感谢您对此的任何帮助。

我的枚举在下面。注意它有一个嵌入的枚举:

public enum AdminPrivilege implements java.io.Serializable {

    // Privileges
    MANAGE_XX("Manage XX", PrivilegeCategory.XX), 
    IMPORT_LICENSE("Import a License", PrivilegeCategory.XX), 
    SUBMIT_BUG("Submit a Bug", PrivilegeCategory.XX), 
    TEST_AD("Test AD", PrivilegeCategory.XX),

    // Administrator Privileges
    LOGIN("Login to XX", PrivilegeCategory.ADMIN), 
    MANAGE_ADMIN("Manage Administrators", PrivilegeCategory.ADMIN), 
    MANAGE_ROLE("Manage Roles", PrivilegeCategory.ADMIN),

    // Task Privileges
    CANCEL_TASK("Cancel Tasks", PrivilegeCategory.TASK), ;

    private static final long serialVersionUID = 1L;

    /**
     * Defines the privilege categories.
     * 
     */
    public enum PrivilegeCategory implements java.io.Serializable {

        XX("XX"), 
        ADMIN("Administrator"), 
        TASK("Task"), ;

        private static final long serialVersionUID = 2L;

        private String displayValue;

        // This constructor is required for GWT serialization
        private PrivilegeCategory() {
        }

        private PrivilegeCategory(String displayValue) {
            this.displayValue = displayValue;
        }

        @Override
        public String toString() {
            return displayValue;
        }
    }

    private String displayValue;
    private AdminPrivilege parentPrivilege;
    private PrivilegeCategory privilegeCategory;

    // This constructor is required for GWT serialization
    private AdminPrivilege() {
    }

    private AdminPrivilege(String displayValue, PrivilegeCategory category) {
        this.displayValue = displayValue;
        this.privilegeCategory = category;
    }

    private AdminPrivilege(String displayValue, PrivilegeCategory category, AdminPrivilege parent) {
        this(displayValue, category);
        this.parentPrivilege = parent;
    }

    /**
     * Return the parent privilege for this privilege.
     * 
     * @return
     */
    public AdminPrivilege getParentPrivilege() {
        return parentPrivilege;
    }

    /**
     * Return the category for this privilege.
     * 
     * @return
     */
    public PrivilegeCategory getPrivilegeCategory() {
        return privilegeCategory;
    }

    /**
     * Return the set of categories.
     * 
     * @return
     */
    public static Set<PrivilegeCategory> getPrivilegeCategories() {
        Set<PrivilegeCategory> category = new HashSet<PrivilegeCategory>();
        for (PrivilegeCategory c : PrivilegeCategory.values()) {
            category.add(c);
        }
        return category;
    }

    /**
     * Return the set of privileges for a category.
     * 
     * @return
     */
    public static Set<AdminPrivilege> getPrivileges(PrivilegeCategory category) {
        Set<AdminPrivilege> privileges = new HashSet<AdminPrivilege>();
        for (AdminPrivilege p : AdminPrivilege.values()) {
            if (category.equals(p.getPrivilegeCategory())) {
                privileges.add(p);
            }
        }
        return privileges;
    }

    /**
     * Return the set of child privileges for a specific privilege
     * 
     * @param parent
     * @return
     */
    public static Set<AdminPrivilege> getChildPrivileges(AdminPrivilege parent) {
        Set<AdminPrivilege> children = new HashSet<AdminPrivilege>();
        for (AdminPrivilege priv : values()) {
            if (parent.equals(priv.getParentPrivilege())) {
                children.add(priv);
            }
        }
        return children;
    }

    /**
     * Return the set of privileges that are parent privileges
     * 
     * @return
     */
        public static Set<AdminPrivilege> getParentPrivileges() {
            Set<AdminPrivilege> parents = new HashSet<AdminPrivilege>();
            for (AdminPrivilege priv : values()) {
                if (priv.getParentPrivilege() == null) {
                    parents.add(priv);
                }
            }
            return parents;
        }

    }

}

【问题讨论】:

  • 这真的很奇怪。默认情况下,一个简单的枚举应该是可序列化的,无需更改。发布您的枚举代码。
  • 嗯 - 它不是一个简单的 Enum - 它有一个嵌入式 Enum。这里是:
  • 这个确切的枚举在 gwt 2.3.0 下对我来说工作正常 - 更多代码上下文?
  • @MarioP - 抱歉,我使用 IsSerializable 添加了版本(这也适用于我)。我正在尝试使用 java.io.Serializable 让它工作。我已经修改了我的帖子以更正它。
  • @PeterD - 我的评论保持不变。在 gwt 2.3.0 中工作正常 - 上下文?

标签: gwt serialization enums


【解决方案1】:

您是否在枚举中指定了参数化构造函数?如果你有,并且它有参数,你需要记住添加一个无参数的构造函数,即使你不使用它,因为 GWT 将需要它。添加参数化构造函数而忘记添加无参数构造函数每次都会让我感到困惑,至少对于非枚举类是这样。

【讨论】:

  • 是的——这就是我所说的无参数构造函数。正如我所说,由于这是一个枚举,构造函数必须是私有的,所以我怀疑这可能是这个问题的根本原因,因为 GWT 声称这是有效的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-15
  • 1970-01-01
  • 2012-02-27
  • 2014-08-20
  • 1970-01-01
相关资源
最近更新 更多