Accès au Backend d’une base de données REST à partir d’une application Android

0
585

Objectif :

L’objectif de cet article est de présenter une méthode permettant l’accès au backed d’une base de données REST à partir d’une application Android, en utilisant MongoDB et Spring IO.

1. Introduction

Les smartphones et les tablettes ne cessent d’accroitre en capacité et en popularité. Ils font désormais part des dispositifs informatiques que nous ramenons avec nous tous les jours, que nous savons comment les utiliser et que nous comptons sur. Ceci continue à offrir des opportunités aux développeurs pour innover dans le domaine des applications mobiles, pour profiter des avantages exclusives des plateformes mobiles que les dispositifs mobiles offrent. Les entreprises sont entrain de déployer des tablettes dans leurs locaux pour améliorer l’expérience client et fournir une plus grande opportunité de revenus. Ces dispositifs disposent d’une connexion sans fil capable de communiquer avec un serveur backend. Un restaurant est un exemple intéressant où les tablettes sont déployées sur chaque table permettant au client de naviguer dans le menu, commander après avoir fait le choix, et payer leurs factures après avoir fini de manger. Avoir un serveur backend centralisé avec lequel communiquent toutes les tablettes permet de révolutionner totalement la gestion des restaurants, analyser les données, dynamiser les menus ou encore améliorer les services. Cet article discute l’une des méthodes permettant l’accès au backend d’une base de données REST à partir d’une application Android. La première section évoquera les outils utilisés, la mise en place de l’environnement et comment créer la base de données du restaurant. La 2ème section de cet article expliquera l’accès à cette base de données à partir d’une application Android.

2. Outils utilisés

Lors de la création d’une preuve de concept, avoir une solution flexible qui permet d’avoir un serveur en place et rapidement opérationnel est souhaitable. La plateforme Spring IO est une solution Open Source qui utilise un serveur Apache Tomcat et permet de se connecter à une variété de base de données. Spring fournit un Framework qui permet d’avoir facilement un client Android et un serveur Linux communiquant à travers une interface REST. Les composants utilisés côté serveurs consistent en un OS Linux Ubuntu 14, une base de données MongoDB et la plate-forme Spring IO pour le service REST. En revanche, ceux utilisés côté client sont l’IDE Android Studio, le template du Spring REST API pour communiquer avec le serveur, la librairie Jackson pour parser la réponse JSON et un AVD en tant qu’émulateur pour démarrer l’application. Visiter les liens ci-dessous pour avoir plus d’informations sur ces composants :

Configuration de l’environnement

Pour configurer l’environnement côté client et côté serveur, suivez les étapes suivantes pour installer Linux, les paquets et Android Studio.

Installez Ubuntu Linux 14 et connectez-vous à un réseau local

http://www.ubuntu.com/download

Installez les paquets à partir du terminal

MongoDB

sudo apt-get update
sudo apt-get install –y mongodb-org

Git

sudo apt-get install git

Gradle

sudo apt-get install gradle

Curl

sudo apt-get install curl

java

sudo add-apt-repository ppa:webupd8team/java 		
sudo apt-get update
sudo apt-get install oracle-java8-installer

Installez Android Studio

https://developer.android.com/sdk/index.html

3. Création de la base de données

Le Spring Starter Project fournit un point de départ intéressant pour créer un backend persistant avec MongoDB qui utilise une interface http JSON pour accéder à la base de données. C’est simple de créer une base de données restaurant qui contient les éléments du menu et les prix. De plus, les requêtes peuvent être définies en quelques lignes de codes. Suivez les étapes ci-dessous pour créer la base de données, créer les requêtes et lancer le service.

Obtenez le Spring Starter Project.

git clone https://github.com/spring-guides/gs-accessing-mongodb-data-rest.git

Naviguez vers le répertoire source initial.

cd gs-accessing-mongodb-data-rest/initial/src/main/java/hello

Créez l’objet Restaurant (Restaurant.java)

import org.springframework.data.annotation.Id;

public class Restaurant {

	@Id private String id;

	private String menuCategoryName;

	private String menuItemName;

	private String menuItemPrice;

	private Boolean isSpecial;

	private String specialmenuItemPrice;


	public String getmenuCategoryName() {

		  return menuCategoryName;		
	
	}

	public void setmenuCategoryName(String menuCategoryName) {

		  this.menuCategoryName = menuCategoryName;	  
	
	}

	public String getmenuItemName() {

		  return menuItemName;
	
	}

	public void setmenuItemName(String menuItemName) {

		  this.menuItemName = menuItemName;
	
	}

	public String getmenuItemPrice() {

		  return menuItemPrice;
	
	}

	public void setmenuItemPrice(String menuItemPrice) {

		  this.menuItemPrice = menuItemPrice;
	
	}

	public Boolean getisSpecial(){

		  return isSpecial;
	
	}

	public void setisSpecial(Boolean isSpecial){

		  this.isSpecial = isSpecial;
	
	}

	public String getspecialmenuItemPrice(){

		  return specialmenuItemPrice;
	
	}

	public void setspecialmenuItemPrice(String specialmenuItemPrice){

		  this.specialmenuItemPrice = specialmenuItemPrice;   
	
	}

}  		

Créez le répertoire de la  base de données Restaurant avec les requêtes (RestaurantRepository.java)

Le chemin de la base de données racine sur le serveur sera http://localhost:8080/menu. 2 requêtes sont définies dans l’interface ci-dessous. findByMenuItemName permet la recherche par menuItemName. findByMenuCategoryName permet la recherche par menuCategoryName.

import java.util.List;

import org.springframework.data.mongodb.repository.MongoRepository;

import org.springframework.data.repository.query.Param;

import org.springframework.data.rest.core.annotation.RepositoryRestResource;


@RepositoryRestResource(collectionResourceRel = "menu", path = "menu")

public interface RestaurantRepository extends MongoRepository {

	List findByMenuItemName(@Param("name") String name);

	List findByMenuCategoryName(@Param("name") String name);

}	

Créez la classe Application (Application.java)

La classe Application affichée ci-dessous est le point d’entrée principal dans le service. Elle inclut la configuration de l’utilisation de Spring IO et MongoDB dans le service.

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.Import;

import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;

 
@Configuration

@EnableMongoRepositories

@Import(RepositoryRestMvcConfiguration.class)

@EnableAutoConfiguration

public class Application {		 

	   public static void main(String[] args) {

			  SpringApplication.run(Application.class, args);

	   }

}

Naviguez vers le répertoire initial :

cd gs-accessing-data-mongodb/initial/

Construisez-la avec Gradle :

./gradlew build

Démarrez le serveur :

java –jar build/libs/<project_name>.jar

Accédez à la base de données :

curl http://localhost:8080/menu

Visualisez la réponse JSON.

Dans cet exemple, la base de données contient un élément du menu « Tacos » :

{

	"_links" : {

	"self" : {

	"href" : "http://localhost:8080/menu{?page,size,sort}",

	"templated" : true

		},

	"search" : {

	"href" : "http://localhost:8080/menu/search"

		}

	},

	"_embedded" : {

	"menu" : [ {

	"menuCategoryName" : "Mexican",

	"menuItemName" : "Tacos",

	"menuItemPrice" : "$15",

	"isSpecial" : false,

	"specialmenuItemPrice" : "$7.50",

	"_links" : {

		"self" : {

			"href" : "http://localhost:8080/menu/5488c2ee44ae7e3fab758edd"

			}

		}

	} ]

},

	"page" : {

	"size" : 20,

	"totalElements" : 1,

	"totalPages" : 1,

	"number" : 0

	}

}

 

4. Accès à la base de données

a. Configuration des permissions et dépendances du projet

Lancez Android Studio et créez un nouveau projet. Une fois le projet créé, vous devez ajouter les permissions internet au fichier manifest, ainsi que les dépendances du template Spring Rest et le parsing du Jacskon JSON comme indiqué ci-dessous :

Ajoutez les permissions Internet au fichier manifest (AndroidManifest.xml)

<uses-permission android:name= « android.permission.INTERNET »>

Ajoutez les dépendances du RestTemplate et de la librairie Jackson (build.gradle)

Appliquez le plugin ‘com.android.application’.

android {

	compileSdkVersion 21

	buildToolsVersion "21.1.1"


	defaultConfig {

		applicationId "com.example.test.myapplication"

		minSdkVersion 7

		targetSdkVersion 21

		versionCode 1

		versionName "1.0"

	}

	buildTypes {

		release {

			minifyEnabled false

			proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

		}

	}

	packagingOptions {

		exclude 'META-INF/ASL2.0'

		exclude 'META-INF/LICENSE'

		exclude 'META-INF/license.txt'

		exclude 'META-INF/NOTICE'

		exclude 'META-INF/notice.txt'

	}

}

dependencies {

	compile 'com.android.support:appcompat-v7:+'

	compile fileTree(dir: 'libs', include: ['*.jar'])

	compile 'org.springframework.android:spring-android-rest-template:1.0.1.RELEASE'

	compile 'com.fasterxml.jackson.core:jackson-databind:2.3.2'

}

b. Parsing de la réponse JSON

L’application a besoin de comprendre la réponse JSON et pouvoir la parser. L’approche consiste à créer des objets Java qui représenteront la réponse. La librairie Jackson est la plus facile à utiliser pour parser les réponses JSON et utiliser les objets Java. Pour utiliser cette librairie, des annotations Jackson sont ajoutées aux objets Java. Ces objets peuvent être créés manuellement, mais il existe un outil pratique qui peut vous assister et les créer pour une réponse JSON donnée en utilisant ce lien (http://www.jsonschema2pojo.org/). La classe « Menu » pour ce cas est illustré ci-dessous avec les annotations Jackson.

package com.example.test.myapplication;

import com.fasterxml.jackson.annotation.JsonAnyGetter;

import com.fasterxml.jackson.annotation.JsonAnySetter;

import com.fasterxml.jackson.annotation.JsonIgnore;

import com.fasterxml.jackson.annotation.JsonInclude;

import com.fasterxml.jackson.annotation.JsonProperty;

import com.fasterxml.jackson.annotation.JsonPropertyOrder;

 
import java.util.HashMap;

import java.util.Map;

	@JsonInclude(JsonInclude.Include.NON_NULL)

	@JsonPropertyOrder({

		"menuCategoryName",

		"menuItemName",

		"menuItemPrice",

		"isSpecial",

		"specialmenuItemPrice",

		"_links"

	})

public class Menu {

	@JsonProperty("menuCategoryName")

	private String menuCategoryName;

	@JsonProperty("menuItemName")

	private String menuItemName;

	@JsonProperty("menuItemPrice")

	private String menuItemPrice;

	@JsonProperty("isSpecial")

	private Boolean isSpecial;

	@JsonProperty("specialmenuItemPrice")

	private String specialmenuItemPrice;

	@JsonProperty("_links")

	private Links_ Links;

	@JsonIgnore

	private Map additionalProperties = new HashMap();

	
	@JsonProperty("menuCategoryName")

	public String getMenuCategoryName() {

		return menuCategoryName;

	}


	@JsonProperty("menuCategoryName")

	public void setMenuCategoryName(String menuCategoryName) { this.menuCategoryName = menuCategoryName; }


	@JsonProperty("menuItemName")

	public String getMenuItemName() {

	return menuItemName;

	}


	@JsonProperty("menuItemName")

	public void setMenuItemName(String menuItemName) {

		this.menuItemName = menuItemName;

	}


	@JsonProperty("menuItemPrice")

	public String getMenuItemPrice() {

		return menuItemPrice;

	}


	@JsonProperty("menuItemPrice")

	public void setMenuItemPrice(String menuItemPrice) {

		this.menuItemPrice = menuItemPrice;

	}


	@JsonProperty("isSpecial")

	public Boolean getIsSpecial() {

		return isSpecial;

	}


	@JsonProperty("isSpecial")

	public void setIsSpecial(Boolean isSpecial) {

		this.isSpecial = isSpecial;

	}


	@JsonProperty("specialmenuItemPrice")

	public String getSpecialmenuItemPrice() {

		return specialmenuItemPrice;

	}


	@JsonProperty("specialmenuItemPrice")

	public void setSpecialmenuItemPrice(String specialmenuItemPrice) { this.specialmenuItemPrice = specialmenuItemPrice; }


	@JsonProperty("_links")

	public Links_ getLinks() {

		return Links;

	}


	@JsonProperty("_links")

	public void setLinks(Links_ Links) {

		this.Links = Links;

	}


	@JsonAnyGetter

	public Map getAdditionalProperties() {

		return this.additionalProperties;

	}


	@JsonAnySetter

	public void setAdditionalProperty(String name, Object value) { this.additionalProperties.put(name, value); }	 

}

 

c. Manipulation de la base de données

La base de données est accessible à travers une simple interface http REST pour exécuter des opérations basiques, tels que POST, PUT, GET et DELETE. Le RestTemplate fournit un bon API pour exécuter ces opérations en AsyncTask, permettant de garder l’application réactive. Le bout de code ci-dessous montre un exemple sur comment accéder et manipuler la base de données restaurant.

Création d’une instance RestTemplate et du chemin de serveur (server path).

private RestTemplate rest = new RestTemplate();

private String url = « http://192.168.1.110:8080/menu/ »;

Activation de la librairie Jackson du parsing JSON.

RestTemplate rest = new RestTemplate();

rest.getMessageConverters().add(new MappingJackson2HttpMessageConverter());

Création d’une instance d’un élément de Menu :

Menu myMenuItem = new Menu();

           myMenuItem.setMenuCategoryName("Mexican");

           myMenuItem.setMenuItemName("Tacos");

           myMenuItem.setMenuItemPrice("$15");

           myMenuItem.setIsSpecial(false);

           myMenuItem.setSpecialmenuItemPrice("$7.50");	

Ajout d’un nouvel élément de menu à la base de données (POST).

L’ajout d’un nouvel élément de menu est une opération POST qui transmet le nouvel élément de menu à la tâche.

new Http_POST_Task().execute(myMenuItem);

private class Http_POST_Task extends AsyncTask {

	@Override

	protected Void doInBackground(Menu... menuItem) {

		try{

		   rest.postForObject(url,menuItem[0],Restaurant.class);

		}

		catch (Exception e) {

			Log.e("MainActivity", e.getMessage(), e);

		}

		return null;

	}

}

Suppression d’un élément de Menu de la base de données (DELETE).

La suppression d’un élément de Menu est une opération DELETE qui transmet l’élément de menu à la Tâche pour être supprimé.

new Http_DELETE_Task().execute(myMenuItem);

private class Http_DELETE_Task extends AsyncTask {

	@Override

	protected Void doInBackground(Menu... menuItem) {

		try {

			//DELETE

			String urlStr = menuItem[0].getLinks().getSelf().getHref();

			rest.delete(new URI(urlStr));

		}

		catch (Exception e) {

			Log.e("MainActivity", e.getMessage(), e);

		}

		return null;

	}

}

Recherche d’un élément de Menu dans la base de données (GET).

La recherche d’un élément de Menu exécute la requête findByMenuItemName pour avoir l’élément souhaité.

try {

	myMenuItem = new Http_findByMenuItemName_Task().execute("Tacos").get();

	} catch (InterruptedException e) {

		e.printStackTrace();

	} catch (ExecutionException e) {

		e.printStackTrace();

	}

private class Http_findByMenuItemName_Task extends AsyncTask {

	@Override

	protected Menu doInBackground(String... menuItemName) {

		try	{

			String queryURL = url+"search/findByMenuItemName?name="+menuItemName[0];

			Restaurant restaurant = rest.getForObject(queryURL, Restaurant.class);

			return restaurant.getEmbedded().getMenu().get(0);

		}

		catch (Exception e) {

			Log.e("MainActivity", e.getMessage(), e);

		}

		return null;

	}

}

Mise à jour d’un élément de menu existant dans la base de données (GET, PUT).

La mise à jour d’un élément existant consiste en une opération GET pour récupérer l’élément existant :

try {

	myMenuItem = new Http_findByMenuItemName_Task().execute("Tacos").get();

	} catch (InterruptedException e) {

		e.printStackTrace();

	} catch (ExecutionException e) {

		e.printStackTrace();

	}

L’élément existant est modifié, puis une opération PUT est exécutée :

	
	myMenuItem.setMenuCategoryName("Chinese");

	myMenuItem.setMenuItemName("Crab Puffs");

	myMenuItem.setMenuItemPrice("$7");

	myMenuItem.setIsSpecial(true);

	myMenuItem.setSpecialmenuItemPrice("$5");

	new Http_PUT_Task().execute(myMenuItem);

private class Http_PUT_Task extends AsyncTask<Menu,Void,Void> {

       @Override

       protected Void doInBackground(Menu... menuItem) {

           try {

			String urlStr = menuItem[0].getLinks().getSelf().getHref();

			rest.put(new URI(urlStr),menuItem[0]);

           }

           catch (Exception e) {

               Log.e("MainActivity", e.getMessage(), e);

           }

           return null;

       }

   }

5. Résumé

Cet article a montré une méthode pour accéder au backend d’une base de données REST à partir d’une application Android. Les outils et l’environnement ont été mentionnés au début. Un exemple de création d’une base de données restaurant avec des requêtes en utilisant MongoDB et SpringIO a été exposé. L’article est fini par montrer comment utiliser le framework Spring IO dans une application Android pour analyser la réponse JSON et comment manipuler la base de données.

AUCUN COMMENTAIRE

LAISSER UN COMMENTAIRE

13 − 7 =