Un client Rest pour Android avec Spring-Android

6

Spring Android est une extension du framework Spring qui, comme son nom l’indique, vise à simplifier les développements Android. Plus précisément, il s’agit du “portage” sur Android de certains modules du framework. Âgée de seulement quelques mois, Spring-Android contient pour le moment RestTemplate et CommonsLogging.

Dans cet article, je vais présenter RestTemplate dans une application Android minimale qui interroge le service web de Google Maps pour récupérer la liste des adresses correspondant à la requête. RestTemplate, pour faire court, facilite le développement d’un client Rest.

Configuration

Commençons par installer Spring-Android. J’utilise Maven pour builder mon application, je déclare donc mes dépendances dans mon pom.xml. En plus de Spring-Android, je vais également utiliser Jackson.

UI

La partie UI de l’application (constituée d’une seule Activity) est très simple : un champs d’édition, un bouton et une ListView qui nous permettra d’afficher les résultats. Voici le layout

et la méthode onCreate de l’activity correspondante

Google Geocode

Le service que je vais utiliser est le service geocode de Google. Il s’interroge de la manière suivante: http://maps.googleapis.com/maps/api/geocode/{format}?address={address}&sensor=false avec format à choisir parmi json et xml et address à remplir par notre requête. Voici donc la manière la plus simple d’interroger ce service.

La méthode getForObject prend en paramètres l’url du service, le type de retour – ici j’ai utilisé le type String pour obtenir la réponse Json brute, mais je vais montrer par la suite qu’on peut faire beaucoup plus acceptable – et les paramètres de l’url. Ici je n’avais qu’un seul paramètre mais on peut en mettre autant qu’on veut.

Jackson

Je vais montrer maintenant comment facilement parser le réponse Json pour obtenir un objet représentant le résultat. Notre requête nous retourne une réponse Json au format décrit dans ce document. On commence par indiquer à notre RestTemplate le convertisseur à utiliser pour les réponses Json. J’utilise ici le convertisseur Json Jackson.

On écrit ensuite les classes de mapping.

Ce que nous renvoie notre service est donc un objet Addresses constitué d’un statut et d’un tableau d’objets de type Address. Il suffit de nommer les propriétés de la même manière qu’elles sont nommées en Json. Pour les adresses, je ne m’intéresse qu’à leur champ formatted_adress, j’utilise donc l’annotation @JsonIgnoreProperties pour lister toutes les propriétés qui ne m’intéressent pas. J’en profite pour redéfinir toString() en vue de l’affichage ultérieur. Il ne me reste plus qu’à demander à mon RestTemplate de m’obtenir un objet Addresses.

Requête Asynchrone

Il est temps maintenant d’insérer notre RestTemplate dans notre Activity. J’appelle le RestTemplate au clic sur le bouton. Mais pour ne pas figer l’UI, j’ai utilisé une AsyncTask.

Résultat

Les sources de l’application sont disponibles sur le Github de Zenika

Spring-Android-Device

Partagez cet article.

A propos de l'auteur

6 commentaires

  1. Très bon example d’utiliser de Spring Android :-)

    J’ai deux questions/ remarques :

    – Tu utilises le Maven Android Plugin.. avec quel IDE ? Eclipse ? En incluant M2Eclipse + m2eclipse-android-integration ? J’ai encore testé il y a quelques semaines, et jme prenais 5 secondes de freeze (rebuild) à chaque sauvegarde d’un fichier de l’appli Android. Comment fais-tu ?

    – @JsonIgnoreProperties permet d’éviter que Jackson lache une erreur en indiquant qu’il a trouvé des propriétés non mappées. En pratique, je préfère configurer Jackson pour ne pas produire d’erreur si une propriété n’est pas mappée. En effet, cela a l’avantage de permettre de faire évoluer l’API Rest (ajout de champs) sans que les clients en soient immédiatement affectés.

  2. Guillaume Gerbaud on

    Merci pour ce tuyau Jackson 😉

    J’utilise Eclipse avec effectivement M2eclipse + m2eclipse-android-integration.

    J’utilise également l’archetype suivant https://github.com/akquinet/android-archetypes  à la création d’un projet.

    Je n’ai aucun problème de freeze.

    Par contre sur un projet que j’ai “Mavenisé”, après une sauvegarde, il arrive que le build Maven se lance plus d’une fois.

  3. Stéphane Nicolas on

    Un très bon article. Cependant, une implémentation plus robuste d’un service de communication pourrait nécessiter une mise en oeuvre plus difficile : les AsyncTask ont un cycle de vie qui est contenu dans celui de l’activité. Si la requête prend un peu de temps, les utilisateur/TRICEs vont vouloir quitter l’activité pour y revenir. Or cela tuera l’AsyncTask. Il vaut alors mieux privilégier un Service pour effectuer la requête, celle-ci pourra s’exécuter quoiqu’il arrive à l’activité qui a initié l’appel REST.

    Une telle solution n’est cependant pas sans problème non plus puisqu’elle va demander la mise en oeuvre d’un processus de communication activité-service qui possède de sérieuses limitations (requiert une forme de sérialization des objets passés en paramètre).

    http://stackoverflow.com/questions/

    L’exemple était très bien fait. Merci.

Ajouter un commentaire