Не удается сериализовать перечисление в GWT

#gwt #serialization #enums

#gwt #сериализация #перечисления

Вопрос:

Я не могу сериализовать перечисление в GWT, если оно реализует java.io.Serializable. Он будет успешно скомпилирован GWT, но во время выполнения я получаю страшное:

Введите ‘com….security..AdminPrivilege’ нельзя было присвоить ‘com.google.gwt.user.client.rpc.IsSerializable’ и у него не было пользовательского сериализатора полей.В целях безопасности этот тип не будет сериализован.: instance = Login to Console (экземпляр = Вход в консоль)

Если я реализую com.google.gwt.user.client.rpc.IsSerializable, он компилируется и работает нормально. Я пытаюсь избежать IsSerializable, поскольку это перечисление сохраняется в нашей базе данных и на него ссылаются сервлеты, отличные от GWT. Я не хочу вводить зависимость от GWT даже для этого единственного класса.

Я прочитал большинство обсуждений по этой теме здесь. У меня есть:

  1. добавлен serialVersionUID (который не должен быть необходимым)
  2. добавлен конструктор без аргументов (но это перечисление, поэтому оно должно быть закрытым — я подозреваю, что это может быть проблемой)
  3. добавлен вызываемый метод RPC, который возвращает перечисление и принимает набор перечислений в качестве входного аргумента (пытается занести это перечисление в белый список) —

Для всех других перечислений я сгенерировал версию GWT, которая реализует IsSerializable. Но это новое перечисление слишком сложно для генерации, и мне нужны методы из перечисления в коде GWT.

Спасибо за любую помощь в этом.

Мое перечисление приведено ниже. Обратите внимание, что в него встроено перечисление:

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

    }

}
  

Комментарии:

1. Это действительно странно. Простое перечисление должно быть сериализуемым по умолчанию без изменений. Опубликуйте свой код перечисления.

2. Ну, это не простое перечисление — в нем есть встроенное перечисление. Вот оно:

3. это точное перечисление отлично работает для меня в gwt 2.3.0 — больше контекста кода?

4. @MarioP — Извините, я добавил версию, используя IsSerializable (что у меня тоже работает). Я пытаюсь заставить его работать, используя java.io.Serializable. Я изменил свой пост, чтобы исправить это.

5. @PeterD — мой комментарий остается прежним. нормально работает в gwt 2.3.0 — context?

Ответ №1:

Указали ли вы параметризованный конструктор в своем перечислении? Если у вас есть, и у него есть параметры, вам нужно не забыть также добавить конструктор без параметров, даже если вы его не используете, потому что он понадобится GWT. Добавление параметризованного конструктора и забывание добавить конструктор без параметров каждый раз приводит меня в замешательство, по крайней мере, в классах, отличных от enum.

Комментарии:

1. Да — это то, что я подразумеваю под конструктором без аргументов. Как я уже сказал, поскольку это перечисление, этот конструктор должен быть закрытым, поэтому я подозреваю, что это может быть основной причиной этой проблемы, поскольку GWT утверждает, что это работает.