Client Androïd REST
Cette article est la suite de l’article sur implémentant d’une architecture REST.
Parmi toutes les API Java intégrées dans le framework Android, il existe le paquetage java.net pour effectuer des requêtes HTTP standard ; c’est-à-dire sans l’intervention d’une bibliothèque externe.
L’usage des classes de ce paquetage implique la configuration totale de vos requêtes HTTP de la méthode utilisée, aux différents timeout et nécessite la conversion manuelle d’un flux de données à une chaîne de caractère.
Pour résumé, si nous désirons effectuer une requête HTTP du type GET, vous devez initialiser la requête de la manière suivante :
public String get(String methode) throws IOException, JSONException {
String url = URL;
InputStream is = null;
String parameters = "";
Log.v("methode", methode);
if(!methode.equals("POST")&&(jsonObj!=null)){
url += jsonObj.getInt("id");
}
if(jsonObj != null){
if(methode.equals("PUT")){
jsonObj.remove("id");
}
parameters = "data="+URLEncoder.encode(jsonObj.toString(), "utf-8");
Log.v("URL", url+" "+parameters);
}
try {
final HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
conn.setRequestMethod(methode);
// Pour les methode POST et PUT on envoie les parametre avec l'OutputStreamWriter
if(methode.equals("POST")||methode.equals("PUT")){
conn.setDoInput(true);
conn.setDoOutput(true);
OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream());
out.write(parameters);// here i sent the parameter
out.close();
}else{
conn.setDoInput(true);
conn.connect();
}
is = conn.getInputStream();
// Lit le InputStream et l'enregistre dans une string
return readIt(is);
} finally {
// Pour etre sur que le InputStream soit ferme apres avoir quitter l'application
if (is != null) {
is.close();
}
}
}
À la lecture de ce code, cela peut vous sembler pas bien complexe à utiliser mais sachez qu’il s’agit ici du minimum syndical. Dès lors que vous voudrez effectuer des requêtes dans un projet sérieux, il vous faudra réagir à des codes HTTP et traiter son contenu en fonction de ce même code. Chose qui n’est pas traitée dans cet exemple, ni même dans ce tutoriel puisque nous verrons plus loin des usages plus courants et plus simples pour effectuer des requêtes.
Vous remarquez aussi l’usage de la méthode readIt(InputStream) qui permet de lire un InputStream et d’en sauvegarder son contenu dans une String. Cette méthode n’existe pas dans Android mais il existe plusieurs façons de mettre en œuvre cette conversion. Voici la mienne :
private String readIt(InputStream is) throws IOException {
BufferedReader r = new BufferedReader(new InputStreamReader(is));
StringBuilder response = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
response.append(line).append('\n');
}
return response.toString();
}
1. Extraction des données JSON
Rappelez-vous, le serveur applicatif va chercher en base de données une liste de produits et renvoyer le résultat dans un fichier JSON. Il faut donc pouvoir extraire les données de ce fichier et les placer dans une classe pour pouvoir les afficher ou les manipuler dans l’application. Pour y parvenir, nous allons déléguer la responsabilité d’extraire les données à une classe Product. Cela permettra de ne plus se préoccuper de l’extraction des « objets » d’un produit dans le fichier JSON.
Avant cela, nous allons en apprendre plus sur les classes principales, à savoir JSONArray et JSONObject.
Pour extraire un tableau d’un fichier JSON, vous devez utiliser la classe JSONArray qui possède 4 constructeurs :
– public JSONArray () : Création d’un tableau JSON vide.
– public JSONArray (Collection copyFrom) : Création d’un tableau JSON en copiant toutes les valeurs de la collection donnée.
– public JSONArray (JSONTokener readFrom) : Création d’un tableau JSON en copiant toutes les valeurs du tableau contenu dans le tokener.
– public JSONArray (String json) : Création d’un tableau JSON suivant un fichier JSON.
Puisque notre requête HTTP lit un InputStream et sauvegarde son contenu dans une String, le dernier constructeur est celui qui convient le mieux à notre exemple. Concrètement, ce constructeur va créer un JSONArray et va contenir toutes les valeurs, les objets ou les tableaux contenus dans le tableau racine. Notez que si le serveur applicatif avait renvoyé non pas un tableau mais un objet, il aurait fallu utiliser un des constructeurs de JSONObject.
Une fois que vous avez votre tableau JSON, une série de méthodes existe pour en extraire les différentes valeurs. Nous avons déjà vu les différentes valeurs contenues dans un fichier JSON, il existe une méthode d’extraction pour chacun de ces types :
– public boolean getBoolean (int index) : Récupérer une valeur booléenne.
– public double getDouble (int index) : Récupérer un double.
– public int getInt (int index) : Récupérer un entier.
– public long getLong (int index) : Récupérer un long.
– public String getString (int index) : Récupérer une chaine de caractères.
– public JSONArray getJSONArray (int index) : Récupérer un tableau JSON.
– public JSONObject getJSONObject (int index) : Récupérer un objet JSON.
2. Extraire les données
La théorie est terminée, nous allons passer à la pratique. L’exemple étant assez simple, il n’y aura qu’une seule classe qui aura la responsabilité d’extraire un JSONObject et de renseigner les valeurs que contient cet objet dans les attributs de la classe, que nous appellerons une classe nommée Product.
package org.libreapps.rest.obj;
import org.json.JSONObject;
public class Product {
private final int id;
private final String name;
private final String type;
private final double price;
public Product(JSONObject jObject) {
this.id =jObject.optInt("id");
this.name = jObject.optString("name");
this.type = jObject.optString("type");
this.price = jObject.optDouble("price");
}
public int getId() { return id; }
public String getName() { return name; }
public String getType() { return type; }
public double getPrice() { return price; }
}
Cependant, avant d’obtenir les objets des produits, il faut itérer sur le tableau JSON qui se trouve à la racine du fichier JSON. Pour ce faire, nous allons récupérer la chaîne de caractères du JSON, nous allons la placer dans un JSONArray et nous allons itérer dessus.
Cependant, avant d’obtenir les objets des produits, il faut itérer sur le tableau JSON qui se trouve à la racine du fichier JSON. Pour ce faire, nous allons récupérer la chaîne de caractères du JSON, nous allons la placer dans un JSONArray et nous allons itérer dessus.
public ArrayList<Product>parse(final String json) { try { final ArrayList products = new ArrayList<>(); final JSONArray jProductArray = new JSONArray(json); for (int i = 0; i < jProductArray.length(); i++) { products.add(new Product(jProductArray.optJSONObject(i))); } return products; } catch (JSONException e) { Log.v("TAG","[JSONException] e : " + e.getMessage()); } return null; }
qsdqsCette méthode ainsi que les méthodes readIt() et get() sont à mettre dans une « AsyncTask » afin de pouvoir l’exécuter en parallèle de notre MainActivity comme dans l’exemple suivant :
public class ConnectionRest extends AsyncTask <String, Void, String> {
private final static String URL = "<URL SERVEUR>";
private JSONObject jsonObj = null;
protected String doInBackground(String... strings) {
try {
List<Product> listProduct = parse(get("GET"));
for (int i=0;i<listProduct.size();i++){
Log.v("PRODUIT ", listProduct.get(i).getName()+" "+listProduct.get(i).getType()+" "+listProduct.get(i).getPrice()+"\n");
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
public void setObj(JSONObject jsonObj){
this.jsonObj = jsonObj;
}
protected void onPostExecute(String s) {
super.onPostExecute(s);
}
}
Dernière chose, nous devons nous assurer que l’appareil a bien accès à internet. Pour cela, nous avons besoin de demander la permission au système dans le Manifest :
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
La suite : Utilisation d’une ListView avec Rest
Code source : https://github.com/emunier/Rest.git
Sources :
https://zestedesavoir.com/tutoriels/1140/communication-entre-android-et-php-mysql/
