组件序列化

所有组件都是可序列化的(serializable),所以你可以为内存或其它存储器序列化组件,之后再拆解它们(so you can serialize components to the memory or other storage and de-serialize them later)。就像克隆,被拆解的组件不属于另一个页面(和桌面)(another page (and desktop))。它们也独立于被序列化的组件。如下所述,序列化可以被用于实现相似的克隆功能。

<vbox id="vb">
   <listbox id="src" multiple="true" width="200px">
      <listhead>
         <listheader label="Population"/>
         <listheader align="right" label="%"/>
      </listhead>
      <listitem value="A">
         <listcell label="A. Graduate"/>
         <listcell label="20%"/>
         </listitem>
      <listitem value="B">
         <listcell label="B. College"/>
         <listcell label="23%"/>
      </listitem>
      <listitem value="C">
         <listcell label="C. High School"/>
         <listcell label="40%"/>
      </listitem>
   </listbox>
   <zscript>
   int cnt = 0;
   </zscript>
   <button label="Clone">
      <attribute name="onClick">
      import java.io.*;
      ByteArrayOutputStream boa = new ByteArrayOutputStream();
      new ObjectOutputStream(boa).writeObject(src);
      Listbox l = new ObjectInputStream(

         new ByteArrayInputStream(boa.toByteArray())).readObject();
      l.setId("dst" + ++cnt);
      vb.insertBefore(l, self);
      </attribute>
   </button>
</vbox>

当然,使用clone方法克隆会有更好的性能,而序列化组件可以被用于不同的机器之间(crossing different machines)。

序列化会话

默认情况下,一个非序列化的实现会被用于表示一个会话(org.zkoss.zk.ui.Session)。使用非序列化实现的好处是不需要担心存储在一个组件内的值,例如Listitem's setValue,是否为可序列化的。

但是,若你想确认存储在组件内的所有值都是可序列化的,可以使用一个序列化的实现表示一个会话。

为了配置ZK使用序列化实现,你需要在WEB-INF/zk.xml 配置factory-class元素,细节请参考the Developer's Reference 的附录B(Appendix B)。

序列化监听器

存储在一个组件,页面,桌面或会话内的属性,变量和监听器也会被序列化,如果它们是可序列化的(且相应的组件,页面,桌面或会话会被序列化)。

为简化可序列化对象的实现,ZK会在序列化前和拆解之后调用序列化监听器,若实现了特定的接口。例如,你可以按如下方式为一个组件实现事件监听器。

public MyListener
implements EventListener, java.io.Serializable, ComponentSerializationListener {
   private transient Component _target; //no need to serialize it

   //ComponentSerializationListener//
   public willSerialize(Component comp) {
   }
   public didDeserialize(Component comp) {
      _target = comp; //restore it back
   }
}

org.zkoss.zk.ui.util.ComponentSerializationListener接口被用于序列化一个组件时。类似的,PageSerializationListenerDesktopSerializationListenSessionSerializationListener 被分别用于序列化一个页面,桌面和会话时。