Хорошо, дай мне посмотреть, понимаю ли я.Вы сказали, что
"Интерфейс использует enum и вызывает EJB-сервис на бэкэнде с перечислением в качестве параметра. Но перечисление часто меняется, поэтому мы не хотим, чтобы бэкэнд знал егозначения "
Когда вы говорите" значения ", я предполагаю, что вы ссылаетесь на числовое значение, которое вы передаете в конструктор перечисления, а не на сами константы перечисления.
Следовательно, это означает, что фронтенд и бэкэнд будут иметь две разные версии класса enum, но константы enum в них будут одинаковыми.
Я только предполагаю, что связьчерез RMI (но это не совсем ясно в вашем посте).
Теперь сериализация / десериализация перечислений работает иначе, чем с другими объектами.Согласно Спецификации Сериализации Java, когда enum сериализуется, сериализуется только его имя.А когда он десериализован, он создается с использованием метода Enum.valueOf (name).
Итак, ваше первоначальное предложение-оболочка не будет работать, поскольку сервер из-за предусмотренной сериализации Enums никогда не узнает фактическоезначение перечислений в клиенте.
Итог, если вы намереваетесь передать перечисление на сервер, нет никакого способа сделать то, что вы притворяетесь, потому что значения во внешнем интерфейсе никогда не достигнут внутреннего уровня.если подразумевается сериализация.
Если подразумевается RMI, хорошим решением было бы использование мобильности кода, таким образом вы могли бы поместить проблемный класс в репозиторий, доступный как для сервера, так и для клиента, и когда разработчики внешнего интерфейсаизменив определение класса, вы можете опубликовать класс в репозитории, и сервер сможет получить его оттуда.
См. эту статью о динамической загрузке кода с использованием свойства base code в RMI http://download.oracle.com/javase/6/docs/technotes/guides/rmi/codebase.html
Другое возможное решение состоит в том, что вы можете прекратить использование Java Enum и использовать класс Javaс конечными константами, как мы делали в старые времена перед перечислениями, и таким образом вы можете быть уверены, что его значения будут правильно сериализованы при отправке на сервер.
Примерно так
public class Fruit implements Serializable{
private static final long serialVersionUID = 1L;
public final Fruit ORANGE = new Fruit("orange");
public final Fruit LEMON = new Fruit("lemon");
private String name;
private Fruit(String name){
this.name = name;
}
}
Таким образом, вы можете полностью контролировать то, что происходит после десериализации, и ваш шаблон оболочки может работать таким образом.
Этот тип конструкции не может полностью заменить перечисление, например, он не может бытьиспользуется в выражениях switch.Но если это проблема, вы можете использовать этот объект в качестве параметра, отправляемого на сервер, и позволить серверу пересобрать из него перечисление с его версией класса перечисления.
Следовательно, ваше перечислениеможет иметь два новых метода, один для создания экземпляров Java из самого перечисления:
public static Fruit toFruit(FruitEnum enum);
public FruitEnum valueOf(Fruit fruit);
И вы можете использовать их для преобразования версий параметра для сервера туда и обратно.