Blog

Jackson : Une librairie pratique pour parser un flux JSON sous android

Bonjour,

Je vais vous parler d’une librairie très pratique dans les projets Android, lorsque vous avez besoin d’interroger des services JSON.

Cette librairie permet de transformer (on dit dé-sérialiser) le flux JSON en objet métier.
On verra à la fin de cet article que l’on peut même faire l’inverse : c’est à dire transformer (dans ce cas on dit sérialiser) un objet métier en flux JSON.

Cette librairie s’appelle JacksonParser. Elle peut s’utiliser sur Android mais aussi dans projet JAVA standard.
Il existe évidemment d’autres librairies mais les avantages de JacksonParser sont :
– sa vélocité
– ses possibilités de configuration
– c’est open-source

Un petit rappel sur ce qu’est JSON:
JSON est un format d’échange de données,
– facile à écrire et à lire
– c’est un format léger
– facilement analysable par un programme

Je vous invite à vous rendre ici : http://jackson.codehaus.org/

et à télécharger
– jackson-core-asl-X.X.X.jar
– jackson-mapper-asl-X.X.X.jar

Une fois ceci fait il faut inclure les 2 fichiers jar dans votre projet et les ajouter au CLASSPATH.

Ensuite je vous conseille de construire vos objets métiers en fonction de la structure du flux JSON que vous lisez.

Voici l’exemple d’un flux JSON

{
	"typeList": "",
	"collabo": [
		{
			"nom": "Abdennadher", "prenom": "Walid"
		},
		{
			"nom": "Hocq", 	"prenom": "Sylvain"
		}
	
	]
}


Et voici comment j’ai créé mes objets métiers pour ce flux.

public class CollaborateurList {
	private List listCollabo;
 
	public List getListCollabo() {
		return listCollabo;
	}
 
	@JsonProperty("collabo")
	public void setListCollabo(List listCollabo) { 
		this.listCollabo = listCollabo;
}} 

public class Collabo {
	String nom;
	@JsonProperty("prenom")
String prenom;
 
	@JsonProperty("nom")
	public void setNom(String nom) {  this.nom = nom; }
 
}

Le mapping entre flux JSON et objet métier, se configure à l’aide d’annotations.
Ici j’utilise uniquement l’annotation @JsonProperty.
Si vous avez bien regardé l’exemple ci-dessus, vous remarquerez que l’on peut poser ces annotations sur des setters mais aussi directement sur des propriétés (voir la propriété prénom ).

L’avantage de passer par des setters, c’est de pouvoir faire des conversions, par exemple: convertir une chaîne de caractères en date avant d’affecter un attribut de l’objet. Le désavantage c’est que c’est un peu plus verbeux…

Une fois les classes métier créées et configurées, il faut créer un objet ObjectMapper comme ceci :

	private static ObjectMapper sMapper = new ObjectMapper();
	static {
		sMapper.configure(Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
	}

Ici on configure le mapper pour qu’il ignore les propriétés sur lesquelles on n’a pas configuré de mapping. Sans cela on aurait une erreur.

Ensuite il n’y a plus qu’à appeler la méthode readValue avec le flux en paramètre et le type d’objet attendu.

String collaboJson = "";
CollaborateurList collaboList = null;
try {
	collaboJson = StreamUtils.inputStreamToString(getAssets().open("collabo.json"));
	collaboList = sMapper.readValue(collaboJson,CollaborateurList.class);
} catch (JsonParseException e) {
	e.printStackTrace();
} 

Remarque sur le type de retour

Dans notre exemple le flux commence par une structure c’est à dire une accolade {
Il faut dans ce cas spécifier le type de retour attendu : ici CollaborateurList.class

Si on a un flux commençant directement par un tableau c’est à dire par un [
Par exemple avec le flux suivant :

[
		{
			"nom": "Abdennadher", "prenom": "Walid"
		},
		{
			"nom": "Hocq", 	"prenom": "Sylvain"
		}
	
]

Dans ce cas on peut utiliser la manière suivante pour faire l’appel à readValue() :

Listlist = sMapper.readValue(collaboJson, new TypeReference>() { });

Et si on veut sérialiser…

Il est possible que vous souhaitiez faire le traitement inverse. Par exemple si vous avez déjà des instances d’objets métiers et que vous souhaitez les convertir en une chaîne JSON, pour par exemple les envoyer dans une requête HTTP POST.
Et bien dans ce cas, il suffit d’appeler la méthode writeValueAsString.

String json = sMapper.writeValueAsString(collaboList);

Dans ce cas il n’y a pas de complication, si l’objet à sérialiser est une liste d’objet métier ou une structure d’objet métier.

Si vous désirez utiliser des annotations sur des méthodes plutôt que sur des attributs (pour faire une transformation en amont par exemple). Il faudra, dans ce cas, déposer des annotations sur les getters.

Résumé :

Un petit résumé pour bien comprendre quand utiliser des getters et setters.
Avant tout, cela est nécessaire uniquement si vous avez besoin de faire une transformation, par exemple convertir une chaîne de caractères en type Date.

Si c’est le cas, il faut bien comprendre ceci: pour sérialiser, le parser à besoin de récupérer les propriétés des objets métier, donc il utilise les getters, donc il faut annoter les getters.
Et pour dé-sérialiser, le parser à besoin d’affecter les propriétés des objets métiers, donc il utilise les setters, qu’il faut annoter.

admin

Written by

The author didnt add any Information to his profile yet

  • j’aime bien la conf simple avec les annotations, et pourtant je suis pas un fan de ça en général :)
    merci !

  • David

    Merci beaucoup pour ce tutorial qui m’a enlevé une épine du pied.