Android News

Aller au contenu | Aller au menu | Aller à la recherche

vendredi 12 juin 2009

Binding JSON/Javabeans avec Jackson

Nous avions déjà vu comment sérialiser des objets en XML en utilisant des annotations, il est également possible de sérialiser/désérialiser des Javabeans en JSON en quelques lignes avec Jackson. Nous pouvons isoler ces lignes de code dans une classe JsonSerializer :

public class JsonSerializer implements Serializer
{
    private ObjectMapper om = new ObjectMapper();

    public void serialize(OutputStream os, Object o) throws IOException
    {
        serialize(new OutputStreamWriter(os), o);
    }

    public void serialize(Writer writer, Object o) throws IOException
    {
        try
        {
            om.writeValue(writer, o);
        } catch (JsonMappingException e)
        {
            System.out.println(e.getMessage());
        }
    }

    public <T> T deserialize(Reader reader, Class<T> clazz) throws IOException
    {
        return om.readValue(reader, clazz);
    }
}

Maintenant, dans un Service ou un Adapter Android, nous pouvons lire/écrire nos Javabeans dans des flux JSON :

JsonSerializer js = new JsonSerializer();

// exemple de sérialisation

js.serialize(flux, new Person("Florent", "Cappelle")
            {{
                    setTels(Arrays.<Tel>asList(new Tel("012345678", Tel.HOME_LANDLINE)));
                    setTels(Arrays.<Tel>asList(new Tel("062345678", Tel.MOBILE_LINE)));
                }}

);

// désérialisation

Person result = js.deserialize(reader, Person.class);

Le mécanisme de sérialisation utilise les noms des getters et les valeurs qu’ils retournent pour générer le flux JSON. Les collections et tableaux sont convertis en leurs équivalents en JSON, ce qui donne par exemple :

{“adresses”:[],”emails”:[], “firstname”:”Florent”, name:”Cappelle”, “tels”:[“number”:”0612345678”, “type”:1]}

Il est possible d’ignorer certains getters en les annotant avec @JsonIgnore et il existe d’autres annotations pour adapter vos Javabeans avec un format JSON prédéfini.

Jackson est donc un choix pertinent pour la stack de développement Google étant donné qu’il fonctionne aussi sur Google App Engine (sans avoir à le modifier contrairement à XStream).

À noter aussi que Jackson fournit des providers pour JAX-RS ainsi qu’une API bas niveau (et donc plus rapide).

lundi 25 mai 2009

Utilisation de XStream sous Android

XStream est une bibliothèque Java qui permet de sérialiser et de désérialiser des objets en s’appuyant sur la réflexion et des Converters pour la plupart des types de base (Float, Integer, Collections, ...). La dernière version (1.3.1) fonctionne plutôt bien sous Android.
Il est possible de paramètrer la sérialisation afin d’adapter une classe Java à un format XML particulier et aussi d’éviter d’avoir le nom complet (avec le package) de la classe dans le XML de sortie. Pour cela, Xstream dispose d’annotations et des méthodes correspondantes dans XStream pour les version de Java antérieures à JavaSE 5.
Exemple avec les annotations :
  1. @XStreamAlias("person")
  2. public class Person implements Serializable {
  3.  
  4.     private String name;
  5.     private String firstname;
  6.  
  7.     @XStreamImplicit(itemFieldName="email")
  8.     private List<Email> emails;
  9.  
  10.     @XStreamImplicit(itemFieldName="tel")
  11.     private List<Tel> tels;
  12.  
  13.     public Person() {
  14.     }
  15.     // utiliser xstream.processAnnotations(Person.class);
  16. }
Et l’équivalent avec les méthodes de XStream :
  1. xstream.alias("person", Person.class);
  2. xstream.addImplicitCollection(Person.class, "emails", "email", Email.class);
  3. xstream.addImplicitCollection(Person.class, "tels", "tel", Tel.class);
Et le résultat de la sérialisation d’un objet Person :
Au niveau des limitations, la plateforme Android ne supporte pas les parseurs StAX et par conséquent le Driver JettisonMappedXmlDriver qui permet de sérialiser/désérialiser en JSON. De plus, XStream s’appuie sur la variable «java.specification.version» afin de déterminer la version de Java : Android fixe cette variable à 0.9, ce qui désactive la gestion des annotations Xstream.
Toutefois, il est possible d’étendre la classe XStream et de redéfinir la méthode qui crée les classes de mapping afin de pouvoir utiliser les annotations Xstream. Il s’agit de la classe AndroidXStream dans l’archive zip associée à ce billet.
L’analyse des annotations est beaucoup plus lente que les méthodes de la classe XStream mais ces dernières rendent le code plus difficile à maintenir à mon goût.
Il est également possible d’utiliser le Driver JsonHierarchicalStreamDriver afin de sérialiser un objet en JSON, par contre la désérialisation n’est pas supportée. Il faudra alors utiliser les classes du package org.json (déjà présent dans l’API Android).
XStream se révèle particulièrement utile avec les Web Services qui utilisent des formats assez complexes. Pour persister des données en local les classes ObjectOutputStream et ObjectInputStream seront plus efficaces.
Vous trouverez un projet d’exemple dans cette archive : XstreamDemo.zip