Čer 2008

Google Web Toolkit a serialization policy

Jelikož momentálně pracuji na jistém projektu EWAIT (Environment for Worthy Algorithms Implementation and Testing) a pro implementaci prezentační vrstvy byl zvolen právě Google Web Toolkit, rozhodl jsem se podělit o několik užitečných poznatků.

Bude se pravděpodobně jednat o sérii několika článků. A hned začneme prvním, dnes o serializaci a deserializaci tříd posílaných přes RPC (tedy AJAX).

GWT je opravdu úžasný framework, ve kterém se dají vytvářet opravdu pěkné RIA. Občas se ale objeví den, který neděláte nic jiného, než prohledáváte nejrůznější fóra, Google Groups a seznam známých bugů neboli issues Google Web Toolkitu.

Pozor na dvakrát vnořené kolekce

GWT při kompilaci vytváří soubor nějaký-hash.gwt.rpc, ve kterém ukládá všechny třídy určené pro serializaci při RPC voláních. Je to proto, aby programátor měl kontrolu nad tím, co přesně se může dostat do klienta (kvůli bezpečnosti).

GWT tedy vezme všechny třídy, které se nachází ve vaší "RemoteService" jakožto parametry nebo návratové typy a ty (pokud implementují rozhraní isSerializable nebo Serializable) zapíše do zmíněného souboru.

Problém nastane však tehdy, když daná třída obsahuje například List (případně jiného potomka Collection), který se skládá z dalších, námi vytvořených tříd, které obsahují další List. Asi to není moc srozumitelné. :-)

Příklad mluví za vše. Řekněme, že chceme naplnit stromek s položkami projekt - verze - měření. Tedy, projekty obsahují verze, které dále obsahují měření.

Soubor "MyService.java":

public interface MyService extends RemoteService
{
  /**
   * @gwt.typeArgs <ProjectItem>
   */
  public List getTreeItems();
}

Soubor "ProjectItem.java":

public class ProjectItem
{
  public title;
  /**
   * @gwt.typeArgs <VersionItem>
   */
  public List versions;
  ...
  ...
}

Soubor "VersionItem.java":

public class VersionItem
{
  public title;
  /**
   * @gwt.typeArgs <MeasurementItem>
   */
  public List measurements;
  ...
  ...
}

Soubor "MeasurementItem.java":

public class MeasurementItem
{
  public title;
  public long duration;
  ...
  ...
}

Pokud teď zavoláte v klientovi getTreeItems(), objeví se tato výjimka:

com.google.gwt.user.client.rpc.SerializationException: Type
'VersionItem' was not included
in the set of types which can be serialized by this
SerializationPolicy. For security purposes, this type will not be
serialized.

Co s tím?

Oprava je až moc jednoduchá, stačí připsat do MyService metodu, která bude vracet typ, jež nám GWT nepovolilo serializovat. V našem případě to je VersionItem, ale i MeasurementItem.

Soubor "MyService.java" po úpravě:

public interface MyService extends RemoteService
{
  /**
   * @gwt.typeArgs <ProjectItem>
   */
  public List getTreeItems();

  public VersionItem dummyVersionItem();

  public MeasurementItem dummyMeasurementItem();
}

Důležité odkazy k této problematice

Ještě dodám, že by tento bug měl být odstraněn ve verzi 1.5, která bude mimochodem už plně podporovat Javu 5! Viz Google Web Toolkit Blog.

Pondělí, 2. 6. 2008 | Štítky: google web toolkit, java