Skip to content

Getting Started

Xi edited this page Oct 24, 2016 · 9 revisions

GWT Version Compatibility Matrix

Please make sure your GWT and gwt-storage versions are compatible.

If you are using GWT version... Then use gwt-storage versions...
GWT 2.8.0 gwt-storage-1.4.0.jar
GWT 2.7.0 gwt-storage-1.3.0.jar
GWT 2.6.x gwt-storage-1.2.1.jar
GWT 2.5.1 gwt-storage-1.2.0.jar
GWT 2.5.1 gwt-storage-1.1.jar
GWT 2.5.0 gwt-storage-1.0.jar

Adding gwt-storage to an GWT Project

Get gwt-storage release

<dependency>
    <groupId>com.seanchenxi.gwt</groupId>
    <artifactId>gwt-storage</artifactId>
    <version>1.4.0</version>
    <scope>provided</scope>
    <!-- 
        If you want to do sever side object2string serialization, 
        you should change the scope to compile
    -->
</dependency>

Configure gwt-storage module

  1. If not using maven, add the jar to your project's classpath, and make sure the GWT compiler can find it
  2. Modify your *.gwt.xml module to inherit gwt-storage support:
<inherits name="com.seanchenxi.gwt.storage.Storage" />
      
  <!-- 
    By default, a simple memory cache is enabled 
    for avoiding long time serialization/deserialization,
    you can disable it, by adding the following line
  -->
<set-property name="storage.cache" value="false" />

<!-- 
  By default, all types that referenced in your RPC interface, 
  will be considered as persistable in web storage. If it isn't what you want,
  add the following line to use a XML file (see next step, for format detail) 
  to provide the persistable class list.

  Since version 1.2.0, you can use StorageKeyProvider to declare persistable classes. 
  The following line could also be used to disable any other finder, 
  if there has no defined serialization xml file     
       
  Available values are: rpc, xml, mix
-->
<set-configuration-property name="storage.type.finder" value="xml"/>

<!-- 
  However, if you want to use both RPC and XML to define persistable classes, 
  Use the following line.
-->
<set-configuration-property name="storage.type.finder" value="mix"/>

Serializing Java objects

The [GWT Client-side Storage API](http://www.gwtproject.org/doc/latest/DevGuideHtml5Storage.html) accepts only string value, anytime you want to store an **object** into web storage, it must be serialized to string. Later, when you want to get it back from web storage, this string value should be deserialized back to **object**.

To realize this, **gwt-storage** reuse the GWT RPC serialization framework. Therefore, All types that needs to store in web storage, must meet the requirements of [RPC serialization](http://www.gwtproject.org/doc/latest/tutorial/RPC.html#serialize GWT) *(implements java.io.Serializable, etc...)*.

How to use...

Considering there are two customized types, we want to store them into web storage (localStorage/sessionStorage)

package com.seanchenxi.gwt.storage.example.client;

import java.io.Serializable;
import java.util.ArrayList;

public class ValueCollection implements Serializable {

  private ArrayList<Value> values;

  public ValueCollection(){}

  public ValueCollection(ArrayList<Value> values){
    this.values = values;
  }
  
}    

and

package com.seanchenxi.gwt.storage.example.client;

import java.io.Serializable;

public class Value implements Serializable{

  private String value;
  
  public Value(){}
  
  public Value(String value){
    this.value = value;
  }
  
}

Declare web storage persistable type

Use StorageKeyProvider to provide the persistable class list (v1.2.0+, recommended)

import com.seanchenxi.gwt.storage.client.StorageKey;
import com.seanchenxi.gwt.storage.client.StorageKeyProvider;
import com.seanchenxi.gwt.storage.example.client.value:
import com.seanchenxi.gwt.storage.example.client.ValueCollection;

public interface MyStorageKeyProvider extends StorageKeyProvider{

    StorageKey<ArrayList<Value>> valueKey();

    StorageKey<boolean[]> boolArrayKey();

    @Key("customKeyName")
    StorageKey<HashMap<Integer, ValueCollection>> valuesMapKey();

    @Key(prefix= "pre-", suffix="-suf")
    StorageKey<ValueCollection> valueCollectionKey(String keyName);
}
  • To get an instance of your StorageKeyProvider:
MyStorageKeyProvider keyProvider = GWT.create(MyStorageKeyProvider.class);
  • StorageKeyProvider will create StorageKey instance when you call the concerned method, and keep it for later use

Use XML file to provide the persistable class list

  • XML file should be named as "storage-serialization.xml", you can also add a prefix if you like.
  • XML file must be stored in your GWT client source folder.
  • Two files: storage-serialization.dtd, storage-serialization.xsd, and one exemple could be helps:
<!DOCTYPE StorageSerialization SYSTEM "storage-serialization.dtd">

<!-- Or, if you want to have xml validation in your IDE, use this:
<!DOCTYPE StorageSerialization PUBLIC "-//seanchenxi.com//DTD Storage Serialization 1.0//EN" 
    "http://seanchenxi.github.io/gwt-storage/dtd/storage-serialization.dtd">
-->

<StorageSerialization>
    <!-- use fully qualified class name -->
    <class>com.seanchenxi.gwt.storage.example.client.ValueCollection</class>
    <class>java.util.ArrayList&lt;com.seanchenxi.gwt.storage.example.client.Value&gt;</class>
    <class>java.util.HashMap&lt;java.lang.Integer,com.seanchenxi.gwt.storage.example.client.ValueCollection&gt;</class>
    ...
</StorageSerialization>
  • You need nothing to do for all primitive types and theirs boxed class

Persist object into web storage

If your are using StorageKeyProvider

In GWT EntryPoint class, use this code :

package com.seanchenxi.gwt.example.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.rpc.SerializationException;
import com.seanchenxi.gwt.storage.client.StorageExt;
import com.seanchenxi.gwt.storage.client.StorageKey;
import com.seanchenxi.gwt.storage.client.StorageKeyFactory;
import com.seanchenxi.gwt.storage.client.StorageQuotaExceededException;
import com.seanchenxi.gwt.storage.example.client.value:
import com.seanchenxi.gwt.storage.example.client.ValueCollection;

/**
 * Illustrative example for storing object into localStorage.
 */
public class StorageExemple implements EntryPoint {

  private final static MyStorageKeyProvider KEY_PROVIDER = GWT.create(MyStorageKeyProvider.class);

  /**
   * This is the entry point method.
   */
  public void onModuleLoad() {

    // get an instance of local storage
    StorageExt localStorage = StorageExt.getLocalStorage();
    assert localStorage != null : "check your browser's HTML 5 support state.";

    storePrimitiveValue(localStorage);
    storeCustomValue(localStorage);

  }


  /**
   * Illustrative example for storing primitive value with StorageKeyProvider
   */
  public void storePrimitiveValue(StorageExt localStorage) {
    
    // create an object (type=boolean[]) to store in local storage
    // make sure you have a declared method in MyStorageKeyProvider.java
    // which return this object type's StorageKey instance (StorageKey<boolean[]>)
    boolean[] boolArrayValue = new boolean[2];
    boolArrayValue[0] = true;
    boolArrayValue[1] = true;

    try {
      
      // put the object into storage
      // the object's storage key will be created/kept by StorageKeyProvider
      localStorage.put(KEY_PROVIDER.boolArrayKey(), boolArrayValue);

    } catch (SerializationException e) {

      // you should treat this exception
      // It happens: when the object type is not recognised as serializable by gwt-storage
      e.printStackTrace(System.err); 

    } catch (StorageQuotaExceededException e) {

      // means the storage is full or no more space for giving value, you should treat this exception
      e.printStackTrace(System.err);
 
    }

    // later...
    
    try {
      
      // later, if you want to get the previous object back
      boolean[] savedBoolArrayValue = localStorage.get(KEY_PROVIDER.boolArrayKey());
      
    } catch (SerializationException e) {
      // It happens when the saved serialized string format is broken
      e.printStackTrace(System.err); 

    }
  }


  /**
   * Illustrative example for storing custom type value with StorageKeyProvider
   */
  public void storeCustomValue(StorageExt localStorage) {  

    // create an object (type=HashMap<Integer, ValueCollection>) to store in local storage
    // make sure you have a declared method in MyStorageKeyProvider.java
    // which return this object type's StorageKey instance (StorageKey<HashMap<Integer, ValueCollection>>)
    HashMap<Integer, ValueCollection> valuesMap = new HashMap<Integer, ValueCollection>();
    for(int i = 1 ; i < 11 ; i++){
      ArrayList<Value> values = new ArrayList<Value>();
      for(int j = 0 ; j < i ; j++){
        values.add(new Value("value" + j));
      }
      valuesMap.put(i, new ValueCollection(values));
    }

    try {
      
      // put the object into storage
      // the object's storage key will be created/kept by StorageKeyProvider
      localStorage.put(KEY_PROVIDER.valuesMapKey(), valuesMap);

    } catch (SerializationException e) {
      // you should treat this exception
      // It happens: when the object type is not recognised as serializable by gwt-storage
      e.printStackTrace(System.err); 
    } catch (StorageQuotaExceededException e) {
      // means the storage is full or no more space for giving value, you should treat this exception
      e.printStackTrace(System.err); 
    }

    // later...
    
    try {
      
      // later, if you want to get the previous object back
      HashMap<Integer, ValueCollection> savedValuesMap = localStorage.get(KEY_PROVIDER.valuesMapKey());
      
    } catch (SerializationException e) {
      // It happens when the saved serialized string format is broken
      // Or the ValueCollection/Value class changed
      e.printStackTrace(System.err); 
    }

  }
}

If your are using storage-serialization.xml or RPC

In GWT EntryPoint class, use this code :

package com.seanchenxi.gwt.example.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.rpc.SerializationException;
import com.seanchenxi.gwt.storage.client.StorageExt;
import com.seanchenxi.gwt.storage.client.StorageKey;
import com.seanchenxi.gwt.storage.client.StorageKeyFactory;
import com.seanchenxi.gwt.storage.client.StorageQuotaExceededException;
import com.seanchenxi.gwt.storage.example.client.value:
import com.seanchenxi.gwt.storage.example.client.ValueCollection;

/**
 * Illustrative example for storing object into localStorage.
 */
public class StorageExemple implements EntryPoint {

  /**
   * This is the entry point method.
   */
  public void onModuleLoad() {

    // get an instance of local storage
    StorageExt localStorage = StorageExt.getLocalStorage();
    assert localStorage != null : "check your browser's HTML 5 support state.";

    storePrimitiveValue(localStorage);
    storeCustomValue(localStorage);

  }


  /**
   * Illustrative example for storing primitive value.
   */
  public void storePrimitiveValue(StorageExt localStorage) {
    
    // create an object to store in local storage
    // make sure this object type is configured in your storage-serialization.xml 
    // or is used in your RPC service
    boolean[] boolArrayValue = new boolean[2];
    boolArrayValue[0] = true;
    boolArrayValue[1] = true;

    // create your object's storage Key
    StorageKey<boolean[]> boolArrayKey = StorageKeyFactory.boolArrayKey("boolArrayKey");

    try {
      
      // put the object into storage
      localStorage .put(boolArrayKey, boolArrayValue);

    } catch (SerializationException e) {

      // you should treat this exception
      // It happens: when the object type is not recognised as serializable by gwt-storage
      e.printStackTrace(System.err); 

    } catch (StorageQuotaExceededException e) {

      // means the storage is full or no more space for giving value, you should treat this exception
      e.printStackTrace(System.err);
 
    }

    // later...
    
    try {
      
      // later, if you want to get the previous object back
      boolean[] savedBoolArrayValue = localStorage.get(boolArrayKey);
      
    } catch (SerializationException e) {
      // It happens when the saved serialized string format is broken
      e.printStackTrace(System.err); 

    }
  }


  /**
   * Illustrative example for storing custom type value.
   */
  public void storeCustomValue(StorageExt localStorage) {  

    // create an object to store in local storage
    // make sure HashMap, ArrayList, ValueCollection and Value are configured in your storage-serialization.xml 
    // or they are used in your RPC service
    HashMap<Integer, ValueCollection> valuesMap = new HashMap<Integer, ValueCollection>();
    for(int i = 1 ; i < 11 ; i++){
      ArrayList<Value> values = new ArrayList<Value>();
      for(int j = 0 ; j < i ; j++){
        values.add(new Value("value" + j));
      }
      valuesMap.put(i, new ValueCollection(values));
    }

    // create your object's storage Key
    StorageKey<HashMap<Integer, ValueCollection>> valuesMapKey = StorageKeyFactory.objectKey("valuesMapKey");

    try {
      
      // put the object into storage
      localStorage.put(valuesMapKey, valuesMap);

    } catch (SerializationException e) {
      // you should treat this exception
      // It happens: when the object type is not recognised as serializable by gwt-storage
      e.printStackTrace(System.err); 
    } catch (StorageQuotaExceededException e) {
      // means the storage is full or no more space for giving value, you should treat this exception
      e.printStackTrace(System.err); 
    }

    // later...
    
    try {
      
      // later, if you want to get the previous object back
      HashMap<Integer, ValueCollection> savedValuesMap = localStorage.get(valuesMapKey);
      
    } catch (SerializationException e) {
      // It happens when the saved serialized string format is broken
      // Or the ValueCollection/Value class changed
      e.printStackTrace(System.err); 
    }

  }
}