Parsing JSON avec Jackson sous Android

Image non disponible

Dans ce tutoriel, nous allons aborder le parsing de fichiers JSON (JavaScript Object Notation) à l'aide de la bibliothèque Jackson.

4 commentaires Donner une note à l'article (4.5)

Article lu   fois.

Les deux auteurs

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

1. Qu'est-ce que JSON ?

JSON est un format léger d'échange de données. Il est facile à écrire et à lire, facilement analysable. C'est un format totalement indépendant de tout langage, ce qui en fait un langage d'échange de données idéal.

Il se base sur deux structures :

  • une collection de couple “Nom / Valeur” ;
  • une liste de valeurs ordonnées.

2. Pourquoi Jackson ?

Pour cet article, nous allons utiliser la bibliothèque Jackson. Vous allez sûrement vous demander “Pourquoi Jackson ?”. Tout simplement parce qu'à mon avis, c'est la meilleure bibliothèque de parsing JSON en général et aussi sous Android. Ce benchmark vous aidera à en être convaincu.
Jackson est une bibliothèque :

  • de Streaming (Lecture / Ecriture) ;
  • rapide ;
  • puissante ;
  • possédant aucune dépendance ;
  • open source ;
  • configurable à souhait.

Vous pouvez obtenir plus d'informations sur le site officiel de Jackson.

3. Mise en place du projet

Pour notre projet, nous allons avoir besoin d'un exemple de fichier JSON. Voici notre petit exemple qui sera disponible sur : users.json.

 
Sélectionnez
{
    "Users": [
        {
            "firstname": "Nazim",
            "lastname": "Benbourahla",
            "login": "n_benbourahla",
            "twitter": "@n_benbourahla",
            "web": ""
        },
        {
            "firstname": "Tutos",
            "lastname": "android",
            "login": "Tutos-android",
            "twitter": "",
            "web": "www.tutos-android.com"
        }
    ]
}

Nous allons créer un projet Android avec les caractéristiques suivantes :

  • nom du projet : TutosAndroidJsonParser ;
  • version du SDK : 2.2 ;
  • nom de l'application : JSON Parser ;
  • package : com.tutos.android.json ;
  • Activité : JsonParserMainActivity.

Nous allons créer un dossier lib à la racine de notre projet dans lequel nous allons mettre les jars de Jackson qui sont disponible ici.
Sans oublier de rajouter les jars au Build Path du projet.

Pour commencer nous allons créer notre vue, qui sera composée d'un bouton et d'un texte pour afficher le JSON.

 
Sélectionnez
<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayout
&#160;&#160;&#160;&#160;xmlns:android="http://schemas.android.com/apk/res/android"
&#160;&#160;&#160;&#160;android:orientation="vertical"
&#160;&#160;&#160;&#160;android:layout_width="match_parent"
&#160;&#160;&#160;&#160;android:layout_height="match_parent"
&#160;&#160;&#160;&#160;>

<Button
&#160;&#160;&#160;&#160;android:layout_width="match_parent"
&#160;&#160;&#160;&#160;android:layout_height="wrap_content"
&#160;&#160;&#160;&#160;android:text="Parser le fichier JSON"
&#160;&#160;&#160;&#160;android:id="@+id/startParsing"
/>

<TextView
&#160;&#160;&#160;&#160;android:layout_width="match_parent"
&#160;&#160;&#160;&#160;android:layout_height="wrap_content"
&#160;&#160;&#160;&#160;android:id="@+id/jsonDisplay"
&#160;&#160;&#160;&#160;/>
</LinearLayout>

Puis nous allons créer nos modèles, correspondant à notre objet User passé dans le JSON.
Voici notre classe User.

 
Sélectionnez
package com.tutos.android.json.model;

public class User {
&#160;&#160;&#160;&#160;private String firstname;
&#160;&#160;&#160;&#160;private String lastname;
&#160;&#160;&#160;&#160;private String login;
&#160;&#160;&#160;&#160;private String twitter;
&#160;&#160;&#160;&#160;private String web;

&#160;&#160;&#160;&#160;public User() {
&#160;&#160;&#160;&#160;super();
&#160;&#160;&#160;&#160;this.firstname = "";
&#160;&#160;&#160;&#160;this.lastname = "";
&#160;&#160;&#160;&#160;this.login = "";
&#160;&#160;&#160;&#160;this.twitter = "";
&#160;&#160;&#160;&#160;this.web = "";
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;public User(String firstName, String lastName, String login,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;String twitter, String web) {
&#160;&#160;&#160;&#160;super();
&#160;&#160;&#160;&#160;this.firstname = firstName;
&#160;&#160;&#160;&#160;this.lastname = lastName;
&#160;&#160;&#160;&#160;this.login = login;
&#160;&#160;&#160;&#160;this.twitter = twitter;
&#160;&#160;&#160;&#160;this.web = web;
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;public String getFirstname() {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;returnfirstname;
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;public void setFirstname(String firstName) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;this.firstname = firstName;
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;public String getLastname() {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return lastname;
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;public void setLastname(String lastName) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;this.lastname = lastName;
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;public String getLogin() {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return login;
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;public void setLogin(String login) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;this.login = login;
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;public String getTwitter() {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return twitter;
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;public void setTwitter(String twitter) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;this.twitter = twitter;
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;public String getWeb() {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return web;
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;public void setWeb(String web) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;this.web = web;
&#160;&#160;&#160;&#160;}

}

Puis la liste des utilisateurs, qui correspond tout simplement à une HashMap de correspondance.

 
Sélectionnez
package com.tutos.android.json.model;

import java.util.ArrayList;
import java.util.HashMap;

public class Users extendsHashMap<String, ArrayList<User>> {

&#160;&#160;&#160;&#160;private static final longserialVersionUID = 1L;

}

Une fois notre modèle prêt, nous allons créer une classe qu'on nommera UserController. Cette classe s'occupera de télécharger et parser notre JSON.

 
Sélectionnez
package com.tutos.android.json.model;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.map.ObjectMapper;

import android.os.Environment;

public class UsersController {

&#160;&#160;&#160;&#160;private static final String DL_URL = "";http://www.tutos-android.com/JSON/users.json

&#160;&#160;&#160;&#160;private ObjectMapper objectMapper = null;
&#160;&#160;&#160;&#160;private JsonFactory jsonFactory = null;
&#160;&#160;&#160;&#160;private JsonParser jp = null;
&#160;&#160;&#160;&#160;private ArrayList<User> userList = null;
&#160;&#160;&#160;&#160;private Users users = null;
&#160;&#160;&#160;&#160;private File jsonOutputFile;
&#160;&#160;&#160;&#160;private File jsonFile;

&#160;&#160;&#160;&#160;public UsersController() {
&#160;&#160;&#160;&#160;objectMapper = newObjectMapper();
&#160;&#160;&#160;&#160;jsonFactory = newJsonFactory();
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;public void init() {
&#160;&#160;&#160;&#160;downloadJsonFile();
&#160;&#160;&#160;&#160;try{
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;jp = jsonFactory.createJsonParser(jsonFile);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;users = objectMapper.readValue(jp, Users.class);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;userList = users.get("Users");
&#160;&#160;&#160;&#160;} catch(JsonParseException e) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;e.printStackTrace();
&#160;&#160;&#160;&#160;} catch(IOException e) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;e.printStackTrace();
&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;private void downloadJsonFile() {
&#160;&#160;&#160;&#160;try{
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;createFileAndDirectory();
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;URL url = new URL(UsersController.DL_URL);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;HttpURLConnection urlConnection;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;urlConnection = (HttpURLConnection) url.openConnection();
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;urlConnection.setRequestMethod("GET");
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;urlConnection.setDoOutput(true);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;urlConnection.connect();
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;FileOutputStream fileOutput = new FileOutputStream(jsonFile);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;InputStream inputStream = urlConnection.getInputStream();
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;byte[] buffer = newbyte[1024];
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;int bufferLength = 0;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;while((bufferLength = inputStream.read(buffer)) > 0) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;fileOutput.write(buffer, 0, bufferLength);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;fileOutput.close();
&#160;&#160;&#160;&#160;} catch(MalformedURLException e) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;e.printStackTrace();
&#160;&#160;&#160;&#160;} catch(IOException e) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;e.printStackTrace();
&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;private void createFileAndDirectory() throws FileNotFoundException {
&#160;&#160;&#160;&#160;final String extStorageDirectory = Environment
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;.getExternalStorageDirectory().toString();
&#160;&#160;&#160;&#160;final String meteoDirectory_path = extStorageDirectory + "/tutos-android";
&#160;&#160;&#160;&#160;jsonOutputFile = new File(meteoDirectory_path, "/");
&#160;&#160;&#160;&#160;if(jsonOutputFile.exists() == false)
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;jsonOutputFile.mkdirs();
&#160;&#160;&#160;&#160;jsonFile = new File(jsonOutputFile, "users.json");
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;public ArrayList<User> findAll() {
&#160;&#160;&#160;&#160;return userList;
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;public User findById(intid) {
&#160;&#160;&#160;&#160;return userList.get(id);
&#160;&#160;&#160;&#160;}

}

Cette classe s'occupera de :

  • créer un dossier “tutos-android” sur le téléphone, puis un fichier users.json (createFileAndDirectory) ;
  • ouvrir une connexion avec le serveur pour lire le contenu du JSON et le recopier localement (downloadJsonFile) ;
  • initialiser notre parseur, à l'aide du fichier JSON local :
 
Sélectionnez
jp = jsonFactory.createJsonParser(jsonFile);
  • Lire des valeurs portant la balise “Users” :
 
Sélectionnez
users = objectMapper.readValue(jp, Users.class);
  • Récupérer de la liste des utilisateurs :
 
Sélectionnez
userList = users.get("Users");

Comme vous venez de le remarquer, parser un fichier JSON est très simple et rapide.

Pour finir, nous allons implémenter notre activité pour :

  • télécharger notre fichier JSON ;
  • afficher le résultat dans le TextView :
 
Sélectionnez
package com.tutos.android.json;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

import com.tutos.android.json.model.User;
import com.tutos.android.json.model.UsersController;

public class JsonParserMainActivity extendsActivity {
&#160;&#160;&#160;&#160;private UsersController usersController;
&#160;&#160;&#160;&#160;private TextView displayJson;

&#160;&#160;&#160;&#160;@Override
&#160;&#160;&#160;&#160;public void onCreate(Bundle savedInstanceState) {
&#160;&#160;&#160;&#160;super.onCreate(savedInstanceState);
&#160;&#160;&#160;&#160;setContentView(R.layout.main);
&#160;&#160;&#160;&#160;usersController = newUsersController();

&#160;&#160;&#160;&#160;displayJson = (TextView) findViewById(R.id.jsonDisplay);

&#160;&#160;&#160;&#160;Button startParsing = (Button) findViewById(R.id.startParsing);
&#160;&#160;&#160;&#160;startParsing.setOnClickListener(newOnClickListener() {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;@Override
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;public void onClick(View view) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;gettingJson();
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;});
&#160;&#160;&#160;&#160;}

&#160;&#160;&#160;&#160;final void gettingJson() {
&#160;&#160;&#160;&#160;final Thread checkUpdate = new Thread() {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;public void run() {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;usersController.init();
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;final StringBuilder str = newStringBuilder("user : ");
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;for(User u : usersController.findAll()) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;str.append("\n").append("first name : ").append(u.getFirstname());
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;str.append("\n").append("last name : ").append(u.getLastname());
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;str.append("\n").append("login : ").append(u.getLogin());
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;str.append("\n").append("twitter : ").append(u.getTwitter());
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;str.append("\n").append("Web : ").append(u.getWeb());
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;runOnUiThread(newRunnable() {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;@Override
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;public void run() {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;displayJson.setText(str.toString());
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;});

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;};
&#160;&#160;&#160;&#160;checkUpdate.start();
&#160;&#160;&#160;&#160;}

}

Ce qui vous donnera le résultat suivant :

Image non disponible

Pour finir je vous fournis le .zip contenant le projet, vous pouvez le télécharger ici.

4. Conclusion

Ce tutoriel s'arrête ici en espérant qu'il vous a aidé a comprendre comment fonctionne le parsing JSON sous Android, l'utilité de la bibliothèque Jackson ainsi que l'avantage que peux procurer JSON sur d'autres formats disponibles comme XML par exemple.

5. Remerciements

Je tiens à remercier tout particulièrement djibril qui a mis ce tutoriel au format Developpez.com.
Merci également à jacques_jean d'avoir pris le temps de le relire et de le corriger.

6. Liens

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2011 Benbourahla Nazim. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.