Должна ли служба GWT-RPC использовать java.io.Serializable в качестве типа параметра? - PullRequest
1 голос
/ 04 апреля 2011

Я определяю простую службу «хранилище ключей-значений» в GWT;Я буду писать сервер, но позволю другим писать клиенты, поэтому все должно быть максимально просто.Я хочу, чтобы клиент мог использовать строковые ключи, но значения любого сериализуемого типа.Итак, я определил интерфейс:

public void put(String key, java.io.Serializable value);
public java.io.Serializable get(String key);

Это прекрасно работает, но есть одна проблема: Eclipse выдает следующее предупреждение обоим методам:

Проверка всех подтипов объекта, которые соответствуют критериямсериализация

Поискивая это предупреждение, похоже, что GWT собирается сгенерировать кусок кода для каждого отдельного типа в программе.Поэтому это может быть довольно дорого.Я запутался, потому что думал, что все типы в интерфейсе Serializable уже имеют код сериализации, и он может просто вызвать его (но, возможно, этот код сериализации генерируется только в этом случае).

Итак, у меня есть номервопросов:

  • Это сделает клиентский код намного а) больше и / или б) медленнее?Насколько серьезна эта проблема?
  • Я вижу, что GWT предоставляет отдельный интерфейс IsSerializable.Могу ли я использовать это вместо этого?Я попробовал это, но заметил, что базовые классы, такие как String и Integer, не реализуют этот интерфейс.
  • Если я заставлю слой RPC использовать вместо byte[], но предоставлю своим клиентам метод обертки для сериализации java.io.Serializable в byte[], обойдет ли это проблему или в итоге возникнет та же проблема, что и у меня? »1023 *
  • Есть ли лучший способ реализовать хранилище значений ключей, которое допускает произвольноезначения типа без особой работы от имени клиента?
  • Если я придерживаюсь Serializable, есть ли способ подавить это предупреждение?

1 Ответ

2 голосов
/ 04 апреля 2011

Я вижу, что 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 будет одинаковой для любого.

...