Ludovic ROLAND

Blog technique sur mes expériences de développeur.

Android : Introduction à Jackson

16 avril 2014

Je vous propose aujourd’hui figurant dans le bloc-note du blog, à savoir un article sur Jackson, une bibliothèque Java permettant de très facilement transformer du JSON en objet Java et ainsi, par exemple, exploiter très facilement et rapidement les résultats d’un web service.

Au cours de cet article, nous allons voir deux exemples d’utilisation :

  • un premier exemple permettant de transformer un contenu JSON en un objet Java ;
  • un second exemple permettant de transformer un contenu JSON en une liste d’objets Java.

Mais avant ça, je vous propose de télécharger et incorporer la bibliothèque dans votre projet Android.

Téléchargement et ajout de Jackson à un projet Android

Les libs

Dans Eclipse, ou Android Studio, créez un project Android tout ce qu’il y a de plus classique. Puis rendez-vous sur le site de Jackson pour télécharger les composants suivants :

  • jackson-annotations-2.2.1.jar
  • jackson-core-2.2.1.jar
  • jackson-databind-2.2.1.jar

Bien évidemment, les numéros de versions peuvent changer.

Une fois téléchargé, déplacez les fichiers dans le dossier libs de votre projet Android et ajoutez les au Build Path.

Maven

Si vous utilisez Maven, ajoutez les dépendances suivantes à votre fichier pom.xml :

<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-annotations</artifactId>
	<version>2.2.1</version>
</dependency>

<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-core</artifactId>
	<version>2.2.1</version>
</dependency>

<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-databind</artifactId>
	<version>2.2.1</version>
</dependency>

Premier exemple : un objet simple

Le JSON

Pour ce premier exemple, le JSON utilisé sera le suivant :

{
    "nom": "ROLAND",
    "prenom": "Ludovic",
    "age": 25
}

Ces données sont placées dans le projet dans le fichier data.json placé dans les assets du projet.

L’objet métier

Nous allons maintenant passer à la modélisation d’un objet métier Personne qui aura pour objectif de mapper les données du fichier JSON. Ainsi, une personne est composée :

  • d’un nom ;
  • d’un prénom ;
  • d’un âge.

Notre objet métier, si l’on ignore Jackson, pourrait ressembler à ça :

public final class Personne {
	
	public final String nom;
	
	public final String prenom;
	
	public final int age;
	
	public Personne(String nom, String prenom, int age) {
		this.nom = nom;
		this.prenom = prenom;
		this.age = age;
	}
}

Nous allons maintenant ajouter la correspondance entre les champs JSON et les champs de notre classe Java à l’aide des annotations Jackson.

La première annotation est l’annotation @JsonCreator qui est à placer au niveau du constructeur.

La seconde annotation est l’annotation @JsonProperty(“xxx”) qui est à placer directement au niveau des paramètres du constructeurs. xxx doit alors être remplacé par la clef du champ du fichier JSON.

Dans le cadre de notre exemple, voici ce à quoi ressemble notre classe Personne.java après la mise en place des annotations Jackson :

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public final class Personne {
	
	public final String nom;
	
	public final String prenom;
	
	public final int age;
	
	@JsonCreator
	public Personne(@JsonProperty("nom") String nom, @JsonProperty("prenom") String prenom, @JsonProperty("age") int age) {
		this.nom = nom;
		this.prenom = prenom;
		this.age = age;
	}
}

La conversion

Nous allons maintenant écrire le petit morceau de code qui permet de transformer le contenu du fichier JSON en un objet Java. Pour celà, nous devons utiliser l’objet ObjectMapper et plus précisémment sa méthode readValue qui dans le cadre de notre premier exemple prend deux paramètres :

  • un InputStream correspondant au contenu du fichier JSON ;
  • une classe correspondant à la classe dans laquelle le JSON doit être transformé.
final ObjectMapper mapper = new ObjectMapper();
final Personne personne = mapper.readValue(stream, Personne.class);

Pour charger le contenu du fichier JSON sous la forme d’un InputStream, la méthode suivante devrait vous rendre service :

final InputStream stream = getResources().getAssets().open("data.json");

Finalement, le code complet est donc le suivant :

try {
	final InputStream stream = getResources().getAssets().open("data.json");
	final ObjectMapper mapper = new ObjectMapper();
	final Personne personne = mapper.readValue(stream, Personne.class);
}
catch (JsonParseException e) {
	e.printStackTrace();
}
catch (JsonMappingException e) {
	e.printStackTrace();
}
catch (IOException e) {
	e.printStackTrace();
}

Vous pouvez afficher dans la console le bon fonctionnement du code en affichant les champs de l’objet Personne via le logger :

Log.d("jackson", personne.nom);
Log.d("jackson", personne.prenom);
Log.d("jackson", String.valueOf(personne.age));

Le résultat, comme en témoigne la capture d’écran ci-dessous, est bien celui attendu :

Deuxième exemple : un tableau d’objets

Le JSON

Pour ce deuxième exemple, considéront le JSON suivant correspondant à un tableau de personnes :

[
    {
        "nom": "ROLAND",
        "prenom": "Ludovic",
        "age": 25
    },
    {
        "nom": "ROBERT",
        "prenom": "John",
        "age": 42
    }
]

Ces données sont placées dans le projet dans le fichier data2.json placé dans les assets du projet.

L’objet métier

L’objet métier à utiliser est strictement le même que dans l’exemple précédent. Rien ne change. ;)

La conversion

Le changement se fait ici. En effet, nous allons toujours utiliser l’objet ObjectMapper et plus précisémment sa méthode readValue, mais dans ce second exemple, les deux paramètres ne sont pas exactement les mêmes que dans l’exemple précédent. Il convient maintenant d’utiliser :

  • un InputStream correspondant au contenu du fichier JSON ;
  • un TypeReference, qui dans notre cas sera une liste de personnes.
final ObjectMapper mapper = new ObjectMapper();
final List<Personne> personnes = mapper.readValue(stream, new TypeReference<List<Personne>>(){});

Pour charger le contenu du fichier JSON sous la forme d’un InputStream, la méthode ne change pas de l’exemple précédent :

final InputStream stream = getResources().getAssets().open("data2.json");

Finalement, le code complet est donc le suivant :

try {
	final InputStream stream = getResources().getAssets().open("data2.json");
	final ObjectMapper mapper = new ObjectMapper();
	final List<Personne> personnes = mapper.readValue(stream, new TypeReference<List<Personne>>(){});
}
catch (JsonParseException e) {
	e.printStackTrace();
}
catch (JsonMappingException e) {
	e.printStackTrace();
}
catch (IOException e) {
	e.printStackTrace();
}

Une nouvelle fois, je vous propose d’utiliser le logger Android afin de vérifier le bon fonctionnement de notre code :

for(final Personne personne : personnes) {
	Log.d("jackson2", personne.nom);
	Log.d("jackson2", personne.prenom);
	Log.d("jackson2", String.valueOf(personne.age));
}

Le résultat, comme en témoigne la capture d’écran ci-dessous, est bien celui attendu :

Commentaires