Я вижу, что GWT предоставляет отдельный интерфейс IsSerializable. Могу ли я использовать это вместо этого? Я попробовал это, но заметил, что базовые классы, такие как String и Integer, не реализуют этот интерфейс.
Да. IsSerializable предпочтительнее, чем java.io.Serializable. В GWT FAQ перечислены причины, по которым это так:
- Семантика сериализации GWT намного менее сложна, чем стандартная сериализация Java, и поэтому использование java.io.Serializable в качестве интерфейса маркера будет означать, что система сериализации GWT способна на большее, чем на самом деле.
- И наоборот, механизм сериализации в GWT проще, чем в стандартном Java, и поэтому использование java.io.Serializable подразумевает, что пользователям нужно больше беспокоиться (например, идентификаторы версий сериализации), чем они на самом деле.
- GWT реализует только подмножество полных классов Java JRE и, в частности, ничего не реализует в java.io. Использование java.io.Serializable в качестве интерфейса маркера сериализации RPC GWT приводит к размыванию сообщения о том, что java.io не может использоваться в приложении GWT.
>
Если я заставлю слой RPC использовать вместо него byte [], но предоставлю своим клиентам метод-обертку для сериализации java.io.Serializable в байт [], это обойдет проблему или закончится та же проблема с раздуванием кода, с которой я начал?
Плохая идея. В этом случае сериализация от объектов к byte [] будет происходить в JavaScript на стороне клиента. Да, сериализация возможна на стороне клиента, но с протоколом GWT; это не сериализация Java. Браузер не будет делать это хорошо.
Есть ли лучший способ реализовать хранилище значений ключей, которое допускает значения произвольного типа без особой работы от имени клиента?
К сожалению, я думаю, вам не удастся избежать использования одного истинного метода для всех классов. Я предлагаю вам попробовать следующий интерфейс:
interface Store<T extends Serializable & IsSerializable> {
void put(String key, String value);
void put(String key, Number value);
void put(String key, T value);
Integer getInt(String key);
Double getDouble(String key);
BigDecimal getBigDecimal(String key);
String getString(String key);
IsSerializable get(String key);
}
Обобщения гарантируют, что объект имеет оба интерфейса, так что вы можете затем сериализовать как с протоколом GWT (от клиента к серверу), так и с сериализацией Java (от сервера к хранилищу данных).
Редактировать Отвечать на комментарии:
С этим последним решением не означает ли универсальное, что хранилище может хранить только один тип объекта, и если клиент хочет сохранить другой, он должен создать новое хранилище?
Да, клиент должен будет создать новое хранилище для каждого типа. Если это действительно беспокоит вас, решение вокруг этого состоит в том, чтобы создать новый интерфейс MySerializable, который расширяет IsSerializable и java.io.Serializable; но тогда каждый объект должен будет реализовать это, что создает зависимость от вашего проекта.
Также не требуется, чтобы объект был как Serializable, так и IsSerializable?
Да, и это преимущество. В противном случае вы рискуете иметь объект на стороне сервера, который не является java.io.Serializable; если вы попытаетесь передать его методу ObjectOutputStream # writeObject , на вашем лице возникнет исключительная ситуация.
Наконец, как насчет моего первого вопроса: действительно ли использование io.Serializable повлияет на размер / производительность кода?
Я не могу сказать это от реального использования, но я так не думаю: оба - просто маркерные интерфейсы. Сериализация GWT будет одинаковой для любого.