#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 даже для этого единственного класса.
Я прочитал большинство обсуждений по этой теме здесь. У меня есть:
- добавлен serialVersionUID (который не должен быть необходимым)
- добавлен конструктор без аргументов (но это перечисление, поэтому оно должно быть закрытым — я подозреваю, что это может быть проблемой)
- добавлен вызываемый метод 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 утверждает, что это работает.