From ea5f4217c43cd9c55f5d08f6f35f5f6896023392 Mon Sep 17 00:00:00 2001 From: Arnaud Tournier Date: Wed, 1 Nov 2017 21:38:29 +0100 Subject: [PATCH] ameliorations --- formation-deploiement-jee-cours/tp - Copie.ad | 41 + .../tp - Copie.html | 501 ++++++++ .../html-css/exercice-html-pur.asciidoc | 37 + .../exemples/html-css/exercice-html-pur.html | 492 ++++++++ .../ExerciceBibliothequeAudio.txt | 79 -- formation-programmation-java/compile.sh | 3 + .../exercice-bibliotheque-audio.ad | 348 ++++++ .../exercice-bibliotheque-audio.html | 1028 +++++++++++++++++ .../exo-javaee-bibliotheque-audio.ad | 40 + .../exo-javaee-bibliotheque-audio.html | 517 +++++++++ .../tp-web-services-discogs.ad | 75 ++ .../tp-web-services-discogs.html | 563 +++++++++ formation-programmation-java/web-services.ad | 6 +- .../web-services.html | 6 +- 14 files changed, 3651 insertions(+), 85 deletions(-) create mode 100644 formation-deploiement-jee-cours/tp - Copie.ad create mode 100644 formation-deploiement-jee-cours/tp - Copie.html create mode 100644 formation-html-css-javascript/exemples/html-css/exercice-html-pur.asciidoc create mode 100644 formation-html-css-javascript/exemples/html-css/exercice-html-pur.html delete mode 100644 formation-programmation-java/ExerciceBibliothequeAudio.txt create mode 100644 formation-programmation-java/exercice-bibliotheque-audio.ad create mode 100644 formation-programmation-java/exercice-bibliotheque-audio.html create mode 100644 formation-programmation-java/exo-javaee-bibliotheque-audio.ad create mode 100644 formation-programmation-java/exo-javaee-bibliotheque-audio.html create mode 100644 formation-programmation-java/tp-web-services-discogs.ad create mode 100644 formation-programmation-java/tp-web-services-discogs.html diff --git a/formation-deploiement-jee-cours/tp - Copie.ad b/formation-deploiement-jee-cours/tp - Copie.ad new file mode 100644 index 0000000..c06d1a2 --- /dev/null +++ b/formation-deploiement-jee-cours/tp - Copie.ad @@ -0,0 +1,41 @@ += Déploiement Java EE - Interrogation + +IUT Blagnac LP APSIO - 2017 - LTE Consulting + +Exercice lié au déploiement d'application Java EE en cluster. + +toc::[] + +== Questions + +1. Comment déploie-t-on une application Java EE sur son serveur d'application ? Quels fichiers sont en jeu ? + +2. Quels sont, avec Java EE, les technologies permettant de répondre dynamiquement à une requête HTTP émise par un navigateur ? + +3. Citez quelques implémentations de serveurs Java EE. + +4. Dans un serveur Java EE, par défaut, où sont stockées les informations de session utilisateur ? + +5. Que se passe-t-il donc si le serveur s'arrête et redémarre inopinément ? + +6. Quel mécanisme au niveau HTTP permet à un serveur Java EE de reconnaître l'utilisateur faisant une requête et de maintenir la session utilisateur ? + +7. En quoi consiste le déploiement d'une application ? + +8. Imaginons que l'on souhaite distribuer une application sur deux machines au lieu d'une, comment s'appelle le composant informatique que l'on peut placer devant les deux serveurs pour répartir la charge équitablement entre les deux ? + +9. Toujours avec le souhait de répartir la charge sur deux serveurs, à quoi va-t-il falloir faire attention et qui peut rendre l'application incohérente aux yeux de l'utilisateur si non pris en compte ? + +10. Quels sont les trois approches vues en TP qui permettent de répartir la charge sur plusieurs serveurs tout en garantissant la cohérence de l'application du point de vue de l'utilisateur ? Expliquez chacune des techniques utilisées. + +11. Qu'appelle-t-on sur un load balancer le comportement en "sticky session" ? Expliquez. + +12. Expliquez le principe de JWT (Json Web Token) en quelques lignes. + +13. Il est possible de configurer le serveur Java EE pour stocker les sessions utilisateurs en base de données. Si on répartit la charge des utilisateurs sur plusieurs serveurs tout en déportant le stockage des sessions sur un SGBD, quel composant informatique va subir une charge importante ? + +14. Donnez quelques arguments en faveur de solutions de containerisation comme Docker, notamment au niveau du déploiement ? + +15. Comment s'appelle le composant logicielle qui permet de gérer de façon automatique le déploiement, l'exécution et la surveillance de container en grand nombre ? + +16. Citez quelques solutions industrielles de ce type. \ No newline at end of file diff --git a/formation-deploiement-jee-cours/tp - Copie.html b/formation-deploiement-jee-cours/tp - Copie.html new file mode 100644 index 0000000..6d2ff16 --- /dev/null +++ b/formation-deploiement-jee-cours/tp - Copie.html @@ -0,0 +1,501 @@ + + + + + + + +Déploiement Java EE - Interrogation + + + + + +
+
+
+
+

IUT Blagnac LP APSIO - 2017 - LTE Consulting

+
+
+

Exercice lié au déploiement d’application Java EE en cluster.

+
+ +
+
+
+

Questions

+
+
+
    +
  1. +

    Comment déploie-t-on une application Java EE sur son serveur d’application ? Quels fichiers sont en jeu ?

    +
  2. +
  3. +

    Quels sont, avec Java EE, les technologies permettant de répondre dynamiquement à une requête HTTP émise par un navigateur ?

    +
  4. +
  5. +

    Citez quelques implémentations de serveurs Java EE.

    +
  6. +
  7. +

    Dans un serveur Java EE, par défaut, où sont stockées les informations de session utilisateur ?

    +
  8. +
  9. +

    Que se passe-t-il donc si le serveur s’arrête et redémarre inopinément ?

    +
  10. +
  11. +

    Quel mécanisme au niveau HTTP permet à un serveur Java EE de reconnaître l’utilisateur faisant une requête et de maintenir la session utilisateur ?

    +
  12. +
  13. +

    En quoi consiste le déploiement d’une application ?

    +
  14. +
  15. +

    Imaginons que l’on souhaite distribuer une application sur deux machines au lieu d’une, comment s’appelle le composant informatique que l’on peut placer devant les deux serveurs pour répartir la charge équitablement entre les deux ?

    +
  16. +
  17. +

    Toujours avec le souhait de répartir la charge sur deux serveurs, à quoi va-t-il falloir faire attention et qui peut rendre l’application incohérente aux yeux de l’utilisateur si non pris en compte ?

    +
  18. +
  19. +

    Quels sont les trois approches vues en TP qui permettent de répartir la charge sur plusieurs serveurs tout en garantissant la cohérence de l’application du point de vue de l’utilisateur ? Expliquez chacune des techniques utilisées.

    +
  20. +
  21. +

    Qu’appelle-t-on sur un load balancer le comportement en "sticky session" ? Expliquez.

    +
  22. +
  23. +

    Expliquez le principe de JWT (Json Web Token) en quelques lignes.

    +
  24. +
  25. +

    Il est possible de configurer le serveur Java EE pour stocker les sessions utilisateurs en base de données. Si on répartit la charge des utilisateurs sur plusieurs serveurs tout en déportant le stockage des sessions sur un SGBD, quel composant informatique va subir une charge importante ?

    +
  26. +
  27. +

    Donnez quelques arguments en faveur de solutions de containerisation comme Docker, notamment au niveau du déploiement ?

    +
  28. +
  29. +

    Comment s’appelle le composant logicielle qui permet de gérer de façon automatique le déploiement, l’exécution et la surveillance de container en grand nombre ?

    +
  30. +
  31. +

    Citez quelques solutions industrielles de ce type.

    +
  32. +
+
+
+
+
+ + + \ No newline at end of file diff --git a/formation-html-css-javascript/exemples/html-css/exercice-html-pur.asciidoc b/formation-html-css-javascript/exemples/html-css/exercice-html-pur.asciidoc new file mode 100644 index 0000000..a06b4af --- /dev/null +++ b/formation-html-css-javascript/exemples/html-css/exercice-html-pur.asciidoc @@ -0,0 +1,37 @@ +[NOTE] +==== +Pour obtenir la documentation sur un type de noeud DOM (`div`, `input`, ...), le mieux est d'aller sur 'Mozilla Developper Network'. Avec google : "html input mdn" (souvent le premier résultat est bon). + +Ne pas aller sur **W3Schools**. +==== + +Créer un fichier `inscription.html` + +Dedans, un titre (`h1`) : "Inscription" + +Un formulaire avec ces champs (utiliser `label`) : + +- "Nom", champ texte +- "Prénom", champ texte +- "Date de naissance", champ date (``) +- "Sexe", deux radios boutons +- "Login", champ texte mais de type 'email' +- "Mot de passe", champ password +- "Intéressé par la newsletter", case à cocher +- "Valider", bouton de validation du formulaire + +En dessous du formulaire un lien "déjà inscrit ? connectez-vous", qui pointe vers la page 'login.html' + + +Créer un autre fichier `login.html` avec un formulaire de login (champs "login" et "mot de passe") + + + + + + + + + + + diff --git a/formation-html-css-javascript/exemples/html-css/exercice-html-pur.html b/formation-html-css-javascript/exemples/html-css/exercice-html-pur.html new file mode 100644 index 0000000..c586dc4 --- /dev/null +++ b/formation-html-css-javascript/exemples/html-css/exercice-html-pur.html @@ -0,0 +1,492 @@ + + + + + + + +Untitled + + + + + +
+
+ + + + + +
+
Note
+
+
+

Pour obtenir la documentation sur un type de noeud DOM (div, input, …​), le mieux est d’aller sur 'Mozilla Developper Network'. Avec google : "html input mdn" (souvent le premier résultat est bon).

+
+
+

Ne pas aller sur W3Schools.

+
+
+
+
+

Créer un fichier inscription.html

+
+
+

Dedans, un titre (h1) : "Inscription"

+
+
+

Un formulaire avec ces champs (utiliser label) :

+
+
+
    +
  • +

    "Nom", champ texte

    +
  • +
  • +

    "Prénom", champ texte

    +
  • +
  • +

    "Date de naissance", champ date (<input type="date"/>)

    +
  • +
  • +

    "Sexe", deux radios boutons

    +
  • +
  • +

    "Login", champ texte mais de type 'email'

    +
  • +
  • +

    "Mot de passe", champ password

    +
  • +
  • +

    "Intéressé par la newsletter", case à cocher

    +
  • +
  • +

    "Valider", bouton de validation du formulaire

    +
  • +
+
+
+

En dessous du formulaire un lien "déjà inscrit ? connectez-vous", qui pointe vers la page 'login.html'

+
+
+

Créer un autre fichier login.html avec un formulaire de login (champs "login" et "mot de passe")

+
+
+ + + \ No newline at end of file diff --git a/formation-programmation-java/ExerciceBibliothequeAudio.txt b/formation-programmation-java/ExerciceBibliothequeAudio.txt deleted file mode 100644 index 962358b..0000000 --- a/formation-programmation-java/ExerciceBibliothequeAudio.txt +++ /dev/null @@ -1,79 +0,0 @@ -_Utilisation des collections pour résoudre un problème concret_ - -On souhaite gérer une bibliothèque de disques audio. - -Voici le diagramme des classes _à minima_, vous aurez bien sûr à ajouter des attributs et des méthodes selon la conception que vous aurez choisie ! - -Classe `Chanson` : - -- attribut *privé* `nom` de type `String`, -- attribut *privé* `duree` de type `int` (durée de la chanson en secondes), -- constructeur et accesseurs. - -Classe `Disque` : - -- attribut *privé* `nom` de type `String`, -- attribut *privé* `codeBarre` de type `String`, -- attribut *privé* `chansons` de type `List`, -- constructeur et accesseurs, -- `addChanson( Chanson chanson )`, -- `getDuree()` retourne la durée totale du disque. - -Classe `Bibliotheque` : - -- les attributs nécessaires, -- `boolean ajouterDisque( Disque disque )`. Cette méthode renvoie false si un disque avec le même code barre existe (et donc le disque n'est pas ajouté), et `true` si le disque a bien été ajouté à la bibliothèque. -- `boolean retirerDisque( String codeBarre )` qui retourne `true` si le disque a bien été retiré, -- `getDisque( String codeBarre )`, -- `List rechercherDisques( String recherche )` : retourne la liste des disques dont le nom contient la chaîne `recherche`, peu importe la casse. -- `List rechercherChansons( String recherche )` : retourne la liste des chansons dont le titre contient `recherche` (sans prendre la casse en compte). - -On considère qu'une fois ajouté à la bibliothèque, les disques et leurs chansons ne changent pas. - -Commencez par implémenter les classes ci-dessus. - -Puis proposez une interface en ligne de commande qui permette à l'utilisateur : - -- de consulter la bibliothèque (chercher les disques par nom). En tapant une recherche il obtiendra la liste des disques correspondant ainsi que leur code barre. -- de consulter les détails d'un disque : en tapant le code barre du disque, il obtient la liste des chansons (nom de la chanson + durée). -- chercher des chansons : en tapant une recherche l'utilisateur reçoit les chansons avec le titre recherché, ainsi que le code barre du disque qui la contient. - -## Interface utilisateur - -Voici le contenu de la classe qui permet de recevoir ce que l'utilisateur a saisi : - - import java.io.BufferedReader; - import java.io.IOException; - import java.io.InputStreamReader; - - public class Saisie - { - public static String saisie( String message ) - { - System.out.println( message ); - System.out.print( "> " ); - - BufferedReader reader = new BufferedReader( new InputStreamReader( System.in ) ); - try - { - return reader.readLine(); - } - catch( IOException e ) - { - e.printStackTrace(); - return null; - } - } - - public static int saisieInt( String message ) - { - String result = saisie( message ); - - return Integer.parseInt( result ); - } - } - - -## Mise en place de l'exception - -- `void ajouterDisque( Disque disque ) throws DisqueDejaPresentException`. Cette méthode provoque une exception `DisqueDejaPresentException` (que vous définirez) lorsqu'on ajoute un disque dont le code barre est déjà enregistré dans la bibliothèque. \ No newline at end of file diff --git a/formation-programmation-java/compile.sh b/formation-programmation-java/compile.sh index 400d21f..627531c 100644 --- a/formation-programmation-java/compile.sh +++ b/formation-programmation-java/compile.sh @@ -8,6 +8,9 @@ asciidoctor exercices-java.ad asciidoctor tp-reseau.ad asciidoctor index.ad asciidoctor tp-morpion.ad +asciidoctor exercice-bibliotheque-audio.ad +asciidoctor exo-javaee-bibliotheque-audio.ad +asciidoctor tp-web-services-discogs.ad asciidoctor -T asciidoctor-reveal.js/templates/slim swing.ad asciidoctor -T asciidoctor-reveal.js/templates/slim java.ad diff --git a/formation-programmation-java/exercice-bibliotheque-audio.ad b/formation-programmation-java/exercice-bibliotheque-audio.ad new file mode 100644 index 0000000..57e71ff --- /dev/null +++ b/formation-programmation-java/exercice-bibliotheque-audio.ad @@ -0,0 +1,348 @@ += Bibliotheque Audio +:author: Arnaud Tournier +:email: ltearno@gmail.com +:toc: macro +:toc-title: Exercices de programmation orientée objet avec Java +:source-highlighter: highlightjs +:imagesdir: images-java + +LTE Consulting (C) - 2017 + +toc::[] + +_Utilisation des collections pour résoudre un problème concret_ + +On souhaite gérer une bibliothèque de disques audio. + +== Implémentation du modèle de données + +Voici le diagramme des classes _à minima_, vous aurez bien sûr à ajouter des attributs et des méthodes selon la conception que vous aurez choisie ! + +Classe `Chanson` : + +- attribut *privé* `nom` de type `String`, +- attribut *privé* `duree` de type `int` (durée de la chanson en secondes), +- constructeur et accesseurs (_getters_ et _setters_), +- méthode `afficher()` qui affiche le nombre de disques ainsi que le détail de chaque disque. + +Classe `Disque` : + +- attribut *privé* `nom` de type `String`, +- attribut *privé* `codeBarre` de type `String`, +- attribut *privé* `chansons` de type `List`, +- constructeur et accesseurs (_getters_ et _setters_), +- `getDuree()` retourne la durée totale du disque, +- méthode `afficher()` qui affiche le nom, le code barre et la durée du disque ainsi que le détail de chacune de ses chansons. + +Classe `Bibliotheque` : + +- attribut *privé* `disques` de type `List`, +- constructeur et accesseurs (_getters_ et _setters_), +- méthode `afficher()` qui affiche le détail de la chanson. + +Commencez par implémenter les classes ci-dessus. + +== Implémentation de la classe principale de l'application + +Pour vérifier que les implémentations sont correctes, écrivez la classe principale suivante : + +[source,language=java] +---- +public class Application { + public static void main() { + Chanson chanson = new Chanson(); + chanson.setTitre("Balade au clair de lune"); + chanson.setDuree(367); + + List chansons = new ArrayList<>(); + chansons.add(chanson); + + Disque disque = new Disque(); + disque.setTitre("Le titre"); + disque.setCodeBarre("ldkshflksjhfdlskdjfhlksdjdfh"); + disque.setChansons(chansons); + + List disques = new ArrayList<>(); + disques.add(disque); + + Bibliotheque bibliotheque = new Bibliotheque(); + bibliotheque.setDisques(disques); + + // affiche l'ensemble de tous les disques et chansons de la bibliothèque. + bibliotheque.afficher(); + } +} +---- + +== Implémentation d'une interface utilisateur + +Nous allons implémenter une interface utilisateur en mode texte. + +A cette fin, vous devez d'abord télécharger une bibliothèque Java contenant une classe qui va vous aider à intéragir avec l'utilisateur. + +Téléchargez le fichier http://lteconsulting.fr/formations/java/OutilsFormation.jar + +Ajoutez cette bibliothèque à votre projet par le biais de votre IDE (Eclipse ou IntelliJ). + +[NOTE] +==== +Sous **Eclipse** : Bouton droit sur le projet / Build Path / Configure Build Path... / onglet "Libraries" / Add external jar... => Choisir le ficher jar téléchargé. + +Sous **IntelliJ** : Menu File / Project Structure... / Libraries / ajouter le fichier jar téléchargé. + +Vous devez grâce à cela avoir accès à la classe `fr.lteconsulting.formations.outils.Saisie`. +==== + +Créez une classe `InterfaceUtilisateur` avec les éléments suivants : + +- attribut *privé* `bibliotheque` de type `Bibliotheque`, +- une méthode *publique* `executer()` qui effectue en boucle le travail de l'interface utilisateur. + +La classe principale ne change pratiquement pas : + +[source,language=java] +---- +public class Application { + public static void main() { + // Préparation de données 'en dur' + Chanson chanson = new Chanson(); + chanson.setTitre("Balade au clair de lune"); + chanson.setDuree(367); + + List chansons = new ArrayList<>(); + chansons.add(chanson); + + Disque disque = new Disque(); + disque.setTitre("Le titre"); + disque.setCodeBarre("ldkshflksjhfdlskdjfhlksdjdfh"); + disque.setChansons(chansons); + + List disques = new ArrayList<>(); + disques.add(disque); + + Bibliotheque bibliotheque = new Bibliotheque(); + bibliotheque.setDisques(disques); + + // Création de l'interface utilisateur + InterfaceUtilisateur ui = new InterfaceUtilisateur(); + ui.setBibliotheque(bibliotheque); + + // Exécution de l'interface utilisateur + ui.executer(); + } +} +---- + +Il ne reste plus qu'à implémenter le corps de la méthode `executer()` de la classe `InterfaceUtilisateur`. + +Voici l'algorithme implémenté par cette méthode : + +- Afficher le menu des actions possibles (avec une numérotation pour permettre à l'utilisateur de choisir dans l'étape suivante). +- Demander à l'utilisateur de saisir son choix (avec la classe `Saisie` fournie dans le fichier jar de tout-à-l'heure). +- Déclenchement de l'action demandée par l'utilisateur. +- On recommence ! + +Voici dans l'ordre de difficulté la liste des actions que vous pouvez proposer à l'utilisateur : + +- Afficher la bibliotheque (simple appel à la méthode `afficher()` que vous avez implémentée tout-à-l'heure). +- Rechercher les disques contenant le texte saisi dans leur titre (et les afficher). +- Rechercher les disques contenant le texte saisi dans leur code barre (et les afficher). +- Recherches les disques contenant des chansons contenant le texte saisi dans leur titre (et les afficher). +- Ajouter un disque par la saisie (l'utilisateur saisit toutes les informations du disque). +- Générer des disques au hasard. +- Supprimer un disque. +- Modifier un disque. +- Sauvegarder la bibliothèque dans un fichier. +- Charger la bibliothèque depuis un fichier. +- Quitter (utiliser `System.exit(0)`). + +=== Affichage du menu + +Vous avez simplement à établir une façon de numéroter (plus précisément identifier) les différents choix possibles dans le menu et à les afficher ligne par ligne avec la méthode `System.out.println("X. Faire qquechose")`. + +Cela doit afficher par exemple : + + 1. Afficher la bibliotheque + 2. Quitter + +=== Analyse de la réponse de l'utilisateur + +Une fois affiché, utilisez la classe `Saisie` pour demander à l'utilisateur de faire son choix. + +Vous récupérez donc un entier correspondant au choix de l'utilisateur (1 pour le choix '1' par exemple). + +Utilisez ensuite l'instruction `switch` pour déclencher l'action correspondant au choix de l'utilisateur. + +Au début, l'implémentation de l'action choisie sera écrite dans la partie `case` du `switch`. Mais très vite, vous pourrez déporter ces traitements dans des méthodes spécifiques (toujours dans la classe `InterfaceUtilisateur`). + +=== Exemples d'intérations + +Voici un exemple d'intéraction entre l'utilisateur et l'application, pour ajouter un disque dans la bibliothèque (les saisies utilisateur sont entourées de `**`) : + +---- +MENU +- 1. Ajouter un disque +- 2. Rechercher par nom +- 3. Rechercher par code barre +- 4. Générer des disques au hasard +- 5. Afficher les disques par nom +- 6. Affichage des disques par code barre +Faites votre choix +> **1** +Nom du disque +> **Toto** +Code barre (laisser vide pour génération aléatoire) +> **[ENTREE]** +Nom de la chanson (laisser vide pour terminer) +> **Une chanson** +Durée de la chanson +> **33** +Nom de la chanson (laisser vide pour terminer) +> **[ENTREE]** + +MENU +- 1. Ajouter un disque +- 2. Rechercher par nom +- 3. Rechercher par code barre +- 4. Générer des disques au hasard +- 5. Afficher les disques par nom +- 6. Affichage des disques par code barre +Faites votre choix +> +---- + +== Génération aléatoire de disques + +Explications... + +Faire une classe `Mots`. + +Y mettre une liste prédéfinie de substantifs (que vous prenez sur google par exemple, à partir d'un terme pour rester dans un même champ lexical). + +On remarque qu'un titre est souvent composé de différents _mots_ avec des _prépositions_ entre eux. Ecrivez donc une méthode `String phraseAuHasard()` qui pioche au hasard des mots et des prépopsitions pour construire une phrase synthétique. + +Utilisez cette classe pour générer des disques et des chansons au hasard. + +[NOTE] +==== +La classe `java.util.Random` permet la génération aléatoire de nombres. + +Par exemple, pour générer un nombre aléatoire compris entre 0 et 3 (non-inclus), on utilisera : `new Random().nextInt( 3 )`. + +La classe `java.util.UUID` permet la génération aléatoire d'identifiants universellement uniques. + +Une façon simple de produire une chaine de caractère est : `String codeBarre = UUID.randomUUID().toString()`. +==== + + +== Codes barres uniques + +Avant d'ajouter un disque dans la bibliothèque, on souhaite vérifier l'unicité de son code barre. + +Pour cela, vous allez ajouter une méthode `boolean ajouterDisque(Disque disque)` à la classe `Bibliotheque`. Cette méthode effectue cette vérification et retourne `true` si le disque a bien été ajouté, ou `false` sinon (pourquoi un disque ne pourrait pas être ajouté ? Car un disque existe déjà avec le même code barre dans la bibliothèque). + +D'autre part, on souhaite s'empêcher de pouvoir modifier la liste des disques d'une bibliotheque directement (par exe : `bibliotheque.getDisques().add(disque)`). La méthode `getDisques()` ne peut donc plus renvoyer de `List`. Pour autant, on souhaite pouvoir continuer à interroger et parcourir la liste de disques contenus dans la bibliothèque (mais sans permettre l'ajout sans contrôle du code barre). Au lieu de renvoyer `List`, renvoyez une `Collection`. Puisque l'interface `List` hérite de `Collection`, seule la signature de la méthode change, et non son implémentation. + +Implémentez dans la méthode `ajouterDisque` un algorithme simple pour empêcher l'insertion d'un disque avec un code barre déjà présent. Quelle est la complexité de cet algorithme (en fonction du nombre N de disques déjà présents dans la bibliothèque) ? + +=== Utilisation d'une Map + +Remplacer dans la classe `Bibliotheque` le type de l'attribut `disques` par `Map` (au lieu de `List`). Faire les modifications adéquates dans le reste de la classe pour que ceci fonctionne. + +Comment la structure de données "table de hachage" (`HashMap`) peut-elle nous aider à avoir un algorithme en `O(1)` pour la méthode `ajouterDisque`? + +[NOTE] +==== +`Collection` est une interface fournie par Java. L'interface `List` en est un sous-type. Cette interface permet entre autres de parcourir une collection sans pouvoir la modifier, ce qui est exactement ce que l'on cherche à faire ici. +==== + +== Sauvegarde et chargement depuis un fichier + +On souhaite maintenant pouvoir sauvegarder notre bibliothèque dans un fichier texte, et la restaurer en lisant une sauvegarde. + +Nous aurons donc deux commandes à implémenter : `SauvegarderCommande` et `ChargerCommande`. + +Format du fichier : + +[source] +---- + * Pour la bibliotheque + * MAGIC_SIGNATURE + * NOMBRE DE DISQUE + * [DISQUES] + * + * Pour chaque disque : + * TITRE + * CODE BARRE + * NOMBRE DE CHANSONS DANS LE DISQUE + * [CHANSONS] + * + * Pour chaque chanson : + * TITRE + * DUREE +---- + +Voici deux sources qui vous permettront de mettre en place cette fonctionalité : + +[source,language=java] +---- +// ouvrir le fichier +writer = new PrintWriter( NOM_FICHIER, "UTF8" ); + +// ecrire dans le fichier +writer.println( "Chaine de caractere à écrire dans le fichier" ); + +// fermer le fichier (TRES IMPORTANT) +writer.close(); +---- + +[source,language=java] +---- +// ouvrir le fichier +File file = new File( NOM_FICHIER ); +FileInputStream fileInputStream = new FileInputStream( file ); +InputStreamReader inputStreamReader = new InputStreamReader( fileInputStream, "UTF8" ); +BufferedReader reader = new BufferedReader( inputStreamReader ); + +// lire une ligne +String line = reader.readLine(); + +// fermer le fichier (TRES IMPORTANT) +reader.close(); +---- + +=== Utilisation de la compression Zip + +Utiliser les tutoriaux suivants : + +https://www.mkyong.com/java/how-to-compress-files-in-zip-format/ pour écrire un zip. + +http://www.mkyong.com/java/how-to-decompress-files-from-a-zip-file/ pour lire le zip. + +== Sauvegarde et chargement depuis une base de données + +Utilisez JDBC pour implémenter cette fonctionalité. + +Adresse du connecteur JDBC pour MySQL : http://search.maven.org/remotecontent?filepath=mysql/mysql-connector-java/5.1.41/mysql-connector-java-5.1.41.jar + +== Proposer une sauvegarde avant de quitter + +Plus : proposer une sauvegarde si une commande a été effectuée depuis le dernier chargement... + +== Utilisation d'une exception + +Création de `DisqueDejaPresentException`... + +- `void ajouterDisque( Disque disque ) throws DisqueDejaPresentException`. Cette méthode provoque une exception `DisqueDejaPresentException` (que vous définirez) lorsqu'on ajoute un disque dont le code barre est déjà enregistré dans la bibliothèque. + +== Menu plus joli + +Soyez _ASCIJI ART_ ! + +== Ajout des _Artistes_ + +Bon, maintenant c'est l'heure d'enrichir le modèle pour ajouter les Auteurs. + +== Solution + +Un corrigé se trouve ici : https://github.com/ltearno/bibliotheque-audio \ No newline at end of file diff --git a/formation-programmation-java/exercice-bibliotheque-audio.html b/formation-programmation-java/exercice-bibliotheque-audio.html new file mode 100644 index 0000000..9a39639 --- /dev/null +++ b/formation-programmation-java/exercice-bibliotheque-audio.html @@ -0,0 +1,1028 @@ + + + + + + + + +Bibliotheque Audio + + + + + +
+ +
+

Implémentation du modèle de données

+
+
+

Voici le diagramme des classes à minima, vous aurez bien sûr à ajouter des attributs et des méthodes selon la conception que vous aurez choisie !

+
+
+

Classe Chanson :

+
+
+
    +
  • +

    attribut privé nom de type String,

    +
  • +
  • +

    attribut privé duree de type int (durée de la chanson en secondes),

    +
  • +
  • +

    constructeur et accesseurs (getters et setters),

    +
  • +
  • +

    méthode afficher() qui affiche le nombre de disques ainsi que le détail de chaque disque.

    +
  • +
+
+
+

Classe Disque :

+
+
+
    +
  • +

    attribut privé nom de type String,

    +
  • +
  • +

    attribut privé codeBarre de type String,

    +
  • +
  • +

    attribut privé chansons de type List<Chanson>,

    +
  • +
  • +

    constructeur et accesseurs (getters et setters),

    +
  • +
  • +

    getDuree() retourne la durée totale du disque,

    +
  • +
  • +

    méthode afficher() qui affiche le nom, le code barre et la durée du disque ainsi que le détail de chacune de ses chansons.

    +
  • +
+
+
+

Classe Bibliotheque :

+
+
+
    +
  • +

    attribut privé disques de type List<Disque>,

    +
  • +
  • +

    constructeur et accesseurs (getters et setters),

    +
  • +
  • +

    méthode afficher() qui affiche le détail de la chanson.

    +
  • +
+
+
+

Commencez par implémenter les classes ci-dessus.

+
+
+
+
+

Implémentation de la classe principale de l’application

+
+
+

Pour vérifier que les implémentations sont correctes, écrivez la classe principale suivante :

+
+
+
+
public class Application {
+	public static void main() {
+		Chanson chanson = new Chanson();
+		chanson.setTitre("Balade au clair de lune");
+		chanson.setDuree(367);
+
+		List<Chanson> chansons = new ArrayList<>();
+		chansons.add(chanson);
+
+		Disque disque = new Disque();
+		disque.setTitre("Le titre");
+		disque.setCodeBarre("ldkshflksjhfdlskdjfhlksdjdfh");
+		disque.setChansons(chansons);
+
+		List<Disque> disques = new ArrayList<>();
+		disques.add(disque);
+
+		Bibliotheque bibliotheque = new Bibliotheque();
+		bibliotheque.setDisques(disques);
+
+		// affiche l'ensemble de tous les disques et chansons de la bibliothèque.
+		bibliotheque.afficher();
+	}
+}
+
+
+
+
+
+

Implémentation d’une interface utilisateur

+
+
+

Nous allons implémenter une interface utilisateur en mode texte.

+
+
+

A cette fin, vous devez d’abord télécharger une bibliothèque Java contenant une classe qui va vous aider à intéragir avec l’utilisateur.

+
+ +
+

Ajoutez cette bibliothèque à votre projet par le biais de votre IDE (Eclipse ou IntelliJ).

+
+
+ + + + + +
+
Note
+
+
+

Sous Eclipse : Bouton droit sur le projet / Build Path / Configure Build Path…​ / onglet "Libraries" / Add external jar…​ ⇒ Choisir le ficher jar téléchargé.

+
+
+

Sous IntelliJ : Menu File / Project Structure…​ / Libraries / ajouter le fichier jar téléchargé.

+
+
+

Vous devez grâce à cela avoir accès à la classe fr.lteconsulting.formations.outils.Saisie.

+
+
+
+
+

Créez une classe InterfaceUtilisateur avec les éléments suivants :

+
+
+
    +
  • +

    attribut privé bibliotheque de type Bibliotheque,

    +
  • +
  • +

    une méthode publique executer() qui effectue en boucle le travail de l’interface utilisateur.

    +
  • +
+
+
+

La classe principale ne change pratiquement pas :

+
+
+
+
public class Application {
+	public static void main() {
+		// Préparation de données 'en dur'
+		Chanson chanson = new Chanson();
+		chanson.setTitre("Balade au clair de lune");
+		chanson.setDuree(367);
+
+		List<Chanson> chansons = new ArrayList<>();
+		chansons.add(chanson);
+
+		Disque disque = new Disque();
+		disque.setTitre("Le titre");
+		disque.setCodeBarre("ldkshflksjhfdlskdjfhlksdjdfh");
+		disque.setChansons(chansons);
+
+		List<Disque> disques = new ArrayList<>();
+		disques.add(disque);
+
+		Bibliotheque bibliotheque = new Bibliotheque();
+		bibliotheque.setDisques(disques);
+
+		// Création de l'interface utilisateur
+		InterfaceUtilisateur ui = new InterfaceUtilisateur();
+		ui.setBibliotheque(bibliotheque);
+
+		// Exécution de l'interface utilisateur
+		ui.executer();
+	}
+}
+
+
+
+

Il ne reste plus qu’à implémenter le corps de la méthode executer() de la classe InterfaceUtilisateur.

+
+
+

Voici l’algorithme implémenté par cette méthode :

+
+
+
    +
  • +

    Afficher le menu des actions possibles (avec une numérotation pour permettre à l’utilisateur de choisir dans l’étape suivante).

    +
  • +
  • +

    Demander à l’utilisateur de saisir son choix (avec la classe Saisie fournie dans le fichier jar de tout-à-l’heure).

    +
  • +
  • +

    Déclenchement de l’action demandée par l’utilisateur.

    +
  • +
  • +

    On recommence !

    +
  • +
+
+
+

Voici dans l’ordre de difficulté la liste des actions que vous pouvez proposer à l’utilisateur :

+
+
+
    +
  • +

    Afficher la bibliotheque (simple appel à la méthode afficher() que vous avez implémentée tout-à-l’heure).

    +
  • +
  • +

    Rechercher les disques contenant le texte saisi dans leur titre (et les afficher).

    +
  • +
  • +

    Rechercher les disques contenant le texte saisi dans leur code barre (et les afficher).

    +
  • +
  • +

    Recherches les disques contenant des chansons contenant le texte saisi dans leur titre (et les afficher).

    +
  • +
  • +

    Ajouter un disque par la saisie (l’utilisateur saisit toutes les informations du disque).

    +
  • +
  • +

    Générer des disques au hasard.

    +
  • +
  • +

    Supprimer un disque.

    +
  • +
  • +

    Modifier un disque.

    +
  • +
  • +

    Sauvegarder la bibliothèque dans un fichier.

    +
  • +
  • +

    Charger la bibliothèque depuis un fichier.

    +
  • +
  • +

    Quitter (utiliser System.exit(0)).

    +
  • +
+
+
+

Affichage du menu

+
+

Vous avez simplement à établir une façon de numéroter (plus précisément identifier) les différents choix possibles dans le menu et à les afficher ligne par ligne avec la méthode System.out.println("X. Faire qquechose").

+
+
+

Cela doit afficher par exemple :

+
+
+
    +
  1. +

    Afficher la bibliotheque

    +
  2. +
  3. +

    Quitter

    +
  4. +
+
+
+
+

Analyse de la réponse de l’utilisateur

+
+

Une fois affiché, utilisez la classe Saisie pour demander à l’utilisateur de faire son choix.

+
+
+

Vous récupérez donc un entier correspondant au choix de l’utilisateur (1 pour le choix '1' par exemple).

+
+
+

Utilisez ensuite l’instruction switch pour déclencher l’action correspondant au choix de l’utilisateur.

+
+
+

Au début, l’implémentation de l’action choisie sera écrite dans la partie case du switch. Mais très vite, vous pourrez déporter ces traitements dans des méthodes spécifiques (toujours dans la classe InterfaceUtilisateur).

+
+
+
+

Exemples d’intérations

+
+

Voici un exemple d’intéraction entre l’utilisateur et l’application, pour ajouter un disque dans la bibliothèque (les saisies utilisateur sont entourées de **) :

+
+
+
+
MENU
+- 1. Ajouter un disque
+- 2. Rechercher par nom
+- 3. Rechercher par code barre
+- 4. Générer des disques au hasard
+- 5. Afficher les disques par nom
+- 6. Affichage des disques par code barre
+Faites votre choix
+> **1**
+Nom du disque
+> **Toto**
+Code barre (laisser vide pour génération aléatoire)
+> **[ENTREE]**
+Nom de la chanson (laisser vide pour terminer)
+> **Une chanson**
+Durée de la chanson
+> **33**
+Nom de la chanson (laisser vide pour terminer)
+> **[ENTREE]**
+
+MENU
+- 1. Ajouter un disque
+- 2. Rechercher par nom
+- 3. Rechercher par code barre
+- 4. Générer des disques au hasard
+- 5. Afficher les disques par nom
+- 6. Affichage des disques par code barre
+Faites votre choix
+>
+
+
+
+
+
+
+

Génération aléatoire de disques

+
+
+

Explications…​

+
+
+

Faire une classe Mots.

+
+
+

Y mettre une liste prédéfinie de substantifs (que vous prenez sur google par exemple, à partir d’un terme pour rester dans un même champ lexical).

+
+
+

On remarque qu’un titre est souvent composé de différents mots avec des prépositions entre eux. Ecrivez donc une méthode String phraseAuHasard() qui pioche au hasard des mots et des prépopsitions pour construire une phrase synthétique.

+
+
+

Utilisez cette classe pour générer des disques et des chansons au hasard.

+
+
+ + + + + +
+
Note
+
+
+

La classe java.util.Random permet la génération aléatoire de nombres.

+
+
+

Par exemple, pour générer un nombre aléatoire compris entre 0 et 3 (non-inclus), on utilisera : new Random().nextInt( 3 ).

+
+
+

La classe java.util.UUID permet la génération aléatoire d’identifiants universellement uniques.

+
+
+

Une façon simple de produire une chaine de caractère est : String codeBarre = UUID.randomUUID().toString().

+
+
+
+
+
+
+

Codes barres uniques

+
+
+

Avant d’ajouter un disque dans la bibliothèque, on souhaite vérifier l’unicité de son code barre.

+
+
+

Pour cela, vous allez ajouter une méthode boolean ajouterDisque(Disque disque) à la classe Bibliotheque. Cette méthode effectue cette vérification et retourne true si le disque a bien été ajouté, ou false sinon (pourquoi un disque ne pourrait pas être ajouté ? Car un disque existe déjà avec le même code barre dans la bibliothèque).

+
+
+

D’autre part, on souhaite s’empêcher de pouvoir modifier la liste des disques d’une bibliotheque directement (par exe : bibliotheque.getDisques().add(disque)). La méthode getDisques() ne peut donc plus renvoyer de List<Disque>. Pour autant, on souhaite pouvoir continuer à interroger et parcourir la liste de disques contenus dans la bibliothèque (mais sans permettre l’ajout sans contrôle du code barre). Au lieu de renvoyer List<Disque>, renvoyez une Collection<Disque>. Puisque l’interface List hérite de Collection, seule la signature de la méthode change, et non son implémentation.

+
+
+

Implémentez dans la méthode ajouterDisque un algorithme simple pour empêcher l’insertion d’un disque avec un code barre déjà présent. Quelle est la complexité de cet algorithme (en fonction du nombre N de disques déjà présents dans la bibliothèque) ?

+
+
+

Utilisation d’une Map

+
+

Remplacer dans la classe Bibliotheque le type de l’attribut disques par Map<String, Disque> (au lieu de List<Disque>). Faire les modifications adéquates dans le reste de la classe pour que ceci fonctionne.

+
+
+

Comment la structure de données "table de hachage" (HashMap) peut-elle nous aider à avoir un algorithme en O(1) pour la méthode ajouterDisque?

+
+
+ + + + + +
+
Note
+
+
+

Collection<T> est une interface fournie par Java. L’interface List<T> en est un sous-type. Cette interface permet entre autres de parcourir une collection sans pouvoir la modifier, ce qui est exactement ce que l’on cherche à faire ici.

+
+
+
+
+
+
+
+

Sauvegarde et chargement depuis un fichier

+
+
+

On souhaite maintenant pouvoir sauvegarder notre bibliothèque dans un fichier texte, et la restaurer en lisant une sauvegarde.

+
+
+

Nous aurons donc deux commandes à implémenter : SauvegarderCommande et ChargerCommande.

+
+
+

Format du fichier :

+
+
+
+
 * Pour la bibliotheque
+ * MAGIC_SIGNATURE
+ * NOMBRE DE DISQUE
+ * [DISQUES]
+ *
+ * Pour chaque disque :
+ * TITRE
+ * CODE BARRE
+ * NOMBRE DE CHANSONS DANS LE DISQUE
+ * [CHANSONS]
+ *
+ * Pour chaque chanson :
+ * TITRE
+ * DUREE
+
+
+
+

Voici deux sources qui vous permettront de mettre en place cette fonctionalité :

+
+
+
+
// ouvrir le fichier
+writer = new PrintWriter( NOM_FICHIER, "UTF8" );
+
+// ecrire dans le fichier
+writer.println( "Chaine de caractere à écrire dans le fichier" );
+
+// fermer le fichier (TRES IMPORTANT)
+writer.close();
+
+
+
+
+
// ouvrir le fichier
+File file = new File( NOM_FICHIER );
+FileInputStream fileInputStream = new FileInputStream( file );
+InputStreamReader inputStreamReader = new InputStreamReader( fileInputStream, "UTF8" );
+BufferedReader reader = new BufferedReader( inputStreamReader );
+
+// lire une ligne
+String line = reader.readLine();
+
+// fermer le fichier (TRES IMPORTANT)
+reader.close();
+
+
+
+

Utilisation de la compression Zip

+
+

Utiliser les tutoriaux suivants :

+
+ + +
+
+
+
+

Sauvegarde et chargement depuis une base de données

+
+
+

Utilisez JDBC pour implémenter cette fonctionalité.

+
+ +
+
+
+

Proposer une sauvegarde avant de quitter

+
+
+

Plus : proposer une sauvegarde si une commande a été effectuée depuis le dernier chargement…​

+
+
+
+
+

Utilisation d’une exception

+
+
+

Création de DisqueDejaPresentException…​

+
+
+
    +
  • +

    void ajouterDisque( Disque disque ) throws DisqueDejaPresentException. Cette méthode provoque une exception DisqueDejaPresentException (que vous définirez) lorsqu’on ajoute un disque dont le code barre est déjà enregistré dans la bibliothèque.

    +
  • +
+
+
+
+
+

Menu plus joli

+
+
+

Soyez ASCIJI ART !

+
+
+
+
+

Ajout des Artistes

+
+
+

Bon, maintenant c’est l’heure d’enrichir le modèle pour ajouter les Auteurs.

+
+
+
+
+

Solution

+
+
+

Un corrigé se trouve ici : https://github.com/ltearno/bibliotheque-audio

+
+
+
+
+ + + + + + \ No newline at end of file diff --git a/formation-programmation-java/exo-javaee-bibliotheque-audio.ad b/formation-programmation-java/exo-javaee-bibliotheque-audio.ad new file mode 100644 index 0000000..48fe454 --- /dev/null +++ b/formation-programmation-java/exo-javaee-bibliotheque-audio.ad @@ -0,0 +1,40 @@ += Exercice Java EE Bibliotheque Audio + +== Création du projet + +- créer un projet _Dynamic Web Project_ nommé "javaee-bibliotheque-audio" + +- reprendre les classes `Bibliotheque`, `Disque` et `Chanson` de l'exercice `bibliotheque-audio`. + +- activer Jax-RS dans votre projet (il faut remplir `web.xml` avec le contenu présenté dans le cours. + +== Classe de service + +Créer un service web REST (avec une nouvelle classe `BibliothequeAudioWebService`). + +L'url de base de ce service sera 'http://localhost:8080/javaee-bibliotheque-audio/api/bibliotheque/' + +Cette classe possèdera un attribut `private static Bibliotheque bibliotheque = new Bibliotheque();` + +NOTE : Pour avoir des disques et des chansons dans la bibliothèque dès le démarrage du serveur, ajouter ceci dans la classe de service : + + // exécute ce bloc d'instruction au chargement de la classe (juste après l'initialisation des attributs `static`) + static { + bibliotheque.genereDisqueAleatoire(50); + } + +Implémenter les méthodes nécessaires pour que le service réponde aux requêtes HTTP suivantes : + +- GET `http://.../api/bibliotheque/disques` : renvoie la liste des disques contenus dans la bibliothèque en JSON, +- GET `http://.../api/bibliotheque/disques/e55-654-334` : renvoie le disque demandé en JSON, +- GET `http://.../api/bibliotheque/disques/e55-654-334/duree` : renvoie la durée en secondes du disque demandé, +- GET `http://.../api/bibliotheque/disques/6e4-455-324/chansons` : la liste des chanson du disque spécifié, +- GET `http://.../api/bibliotheque/disques/6e4-455-324/chansons/4` : renvoie la 5ième chanson du disque spécifié, +- POST `http://.../api/bibliotheque/disques` : ajout d'un disque à partir de la représentation JSON du disque à ajouter (se trouvant dans la requête), +- POST `http://.../api/bibliotheque/disques/6e4-455-324/chansons` : ajouter une chanson (en JSON dans le body de la req) dans le disque spécifié, + +Utiliser le logiciel PostMan pour tester et vérifier le bon fonctionnement de votre programme. + +- GET `http://.../api/bibliotheque/disques/search?name=coucou` : renvoie la liste des disques contenant la chaine de caractère 'coucou' dans leur titre. + +Ajouter ensuite les urls pour les effacements (méthode/verbe DELETE) puis les mises à jour (méthode/verbe PUT). \ No newline at end of file diff --git a/formation-programmation-java/exo-javaee-bibliotheque-audio.html b/formation-programmation-java/exo-javaee-bibliotheque-audio.html new file mode 100644 index 0000000..fcafb9b --- /dev/null +++ b/formation-programmation-java/exo-javaee-bibliotheque-audio.html @@ -0,0 +1,517 @@ + + + + + + + +Exercice Java EE Bibliotheque Audio + + + + + +
+
+

Création du projet

+
+
+
    +
  • +

    créer un projet Dynamic Web Project nommé "javaee-bibliotheque-audio"

    +
  • +
  • +

    reprendre les classes Bibliotheque, Disque et Chanson de l’exercice bibliotheque-audio.

    +
  • +
  • +

    activer Jax-RS dans votre projet (il faut remplir web.xml avec le contenu présenté dans le cours.

    +
  • +
+
+
+
+
+

Classe de service

+
+
+

Créer un service web REST (avec une nouvelle classe BibliothequeAudioWebService).

+
+
+

L’url de base de ce service sera 'http://localhost:8080/javaee-bibliotheque-audio/api/bibliotheque/'

+
+
+

Cette classe possèdera un attribut private static Bibliotheque bibliotheque = new Bibliotheque();

+
+
+

NOTE : Pour avoir des disques et des chansons dans la bibliothèque dès le démarrage du serveur, ajouter ceci dans la classe de service :

+
+
+
+
// exécute ce bloc d'instruction au chargement de la classe (juste après l'initialisation des attributs `static`)
+static {
+	bibliotheque.genereDisqueAleatoire(50);
+}
+
+
+
+

Implémenter les méthodes nécessaires pour que le service réponde aux requêtes HTTP suivantes :

+
+
+ +
+
+

Utiliser le logiciel PostMan pour tester et vérifier le bon fonctionnement de votre programme.

+
+
+ +
+
+

Ajouter ensuite les urls pour les effacements (méthode/verbe DELETE) puis les mises à jour (méthode/verbe PUT).

+
+
+
+
+ + + \ No newline at end of file diff --git a/formation-programmation-java/tp-web-services-discogs.ad b/formation-programmation-java/tp-web-services-discogs.ad new file mode 100644 index 0000000..3deb65b --- /dev/null +++ b/formation-programmation-java/tp-web-services-discogs.ad @@ -0,0 +1,75 @@ += TP Web Services Utilisation de Discogs avec la bibliotheque Audio +:author: Arnaud Tournier +:email: ltearno@gmail.com +:toc: macro +:toc-title: TP Web Services +:imagesdir: images-struts +:source-highlighter: highlightjs + +LTE Consulting (C) - 2017 + +toc::[] + +== Exercice + +L'objectif est d'alimenter notre bibliothèque avec des données fournies par le service Discogs (https://www.discogs.com). + +Nous travaillons sur le project `javaee-bibliotheque-audio`. + +L'idée est d'avoir une servlet interne à notre projet, répondant à l'url `/importationDiscogs` qui se chargera de consommer le service Discogs pour importer des disques. + +== Consommation d'un client REST + +=== Lire la documentation du service + +Lire la page https://www.discogs.com/developers/ + +On y apprend par exemple qu'en faisant une requête `GET` à l'url `https://api.discogs.com/releases/24950`, on obtient les informations sur le disque identifié 24950 chez Discogs. + +Essayez de faire cette requête avec votre navigateur ou PostMan. + +Cette url est documentée ici : https://www.discogs.com/developers/#page:database,header:database-release. + +Observer la structure des données reçues. + +Dans le projet java, définissez le contrat pour l'API de `discogs` sous la forme d'une interface Java compatible avec `JAX-RS`. + +Toujours dans ce projet, définir les classes Java correspondant aux données envoyées par le service. Voici un court début : + +[source,language=java] +---- +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +// Classe Java représentant les Releases chez Discogs +// Permet d'ignorer les champs dans le JSON qui ne sont pas définis dans la classe Java +@JsonIgnoreProperties( ignoreUnknown = true ) +public class DiscogsRelease +{ + public List styles; + public int year; + public String title; + // ... +} +---- + +== Utilisation avancée + +Pour certaines requêtes, Discogs demande la création d'un compte. Voici quelques informations. + +=== Création du compte Discogs + +Créez un compte sur le site. + +Pour info, Discogs demande la création de compte pour pouvoir gérer les appels de services que vous consommerez. + +=== Paramétrage du compte + +NOTE **CECI N'EST PAS OBLIGATOIRE POUR LES REQUETES DE BASE, COMME ALLER CHERCHER UN DISQUE. A NE PAS FAIRE DES LE DEBUT DONC** + +Dans les paramètres de votre compte, allez dans la partie **Developers** et créez une application. Cela va vous permettre de générer deux informations dont vous aurez besoins pour appeler le service : + +- le `Consumer Key` et +- le `Consumer Secret`. + +Ce sont l'équivalent des mots de passes, mais dans le contexte ou une application (la vôtre) discute avec une autre (discogs). + diff --git a/formation-programmation-java/tp-web-services-discogs.html b/formation-programmation-java/tp-web-services-discogs.html new file mode 100644 index 0000000..af82815 --- /dev/null +++ b/formation-programmation-java/tp-web-services-discogs.html @@ -0,0 +1,563 @@ + + + + + + + + +TP Web Services Utilisation de Discogs avec la bibliotheque Audio + + + + + +
+ +
+

Exercice

+
+
+

L’objectif est d’alimenter notre bibliothèque avec des données fournies par le service Discogs (https://www.discogs.com).

+
+
+

Nous travaillons sur le project javaee-bibliotheque-audio.

+
+
+

L’idée est d’avoir une servlet interne à notre projet, répondant à l’url /importationDiscogs qui se chargera de consommer le service Discogs pour importer des disques.

+
+
+
+
+

Consommation d’un client REST

+
+
+

Lire la documentation du service

+ +
+

On y apprend par exemple qu’en faisant une requête GET à l’url https://api.discogs.com/releases/24950, on obtient les informations sur le disque identifié 24950 chez Discogs.

+
+
+

Essayez de faire cette requête avec votre navigateur ou PostMan.

+
+ +
+

Observer la structure des données reçues.

+
+
+

Dans le projet java, définissez le contrat pour l’API de discogs sous la forme d’une interface Java compatible avec JAX-RS.

+
+
+

Toujours dans ce projet, définir les classes Java correspondant aux données envoyées par le service. Voici un court début :

+
+
+
+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+// Classe Java représentant les Releases chez Discogs
+// Permet d'ignorer les champs dans le JSON qui ne sont pas définis dans la classe Java
+@JsonIgnoreProperties( ignoreUnknown = true )
+public class DiscogsRelease
+{
+	public List<String> styles;
+	public int year;
+	public String title;
+	// ...
+}
+
+
+
+
+
+
+

Utilisation avancée

+
+
+

Pour certaines requêtes, Discogs demande la création d’un compte. Voici quelques informations.

+
+
+

Création du compte Discogs

+
+

Créez un compte sur le site.

+
+
+

Pour info, Discogs demande la création de compte pour pouvoir gérer les appels de services que vous consommerez.

+
+
+
+

Paramétrage du compte

+
+

NOTE CECI N’EST PAS OBLIGATOIRE POUR LES REQUETES DE BASE, COMME ALLER CHERCHER UN DISQUE. A NE PAS FAIRE DES LE DEBUT DONC

+
+
+

Dans les paramètres de votre compte, allez dans la partie Developers et créez une application. Cela va vous permettre de générer deux informations dont vous aurez besoins pour appeler le service :

+
+
+
    +
  • +

    le Consumer Key et

    +
  • +
  • +

    le Consumer Secret.

    +
  • +
+
+
+

Ce sont l’équivalent des mots de passes, mais dans le contexte ou une application (la vôtre) discute avec une autre (discogs).

+
+
+
+
+
+ + + + + + \ No newline at end of file diff --git a/formation-programmation-java/web-services.ad b/formation-programmation-java/web-services.ad index 242d89e..e9b986e 100644 --- a/formation-programmation-java/web-services.ad +++ b/formation-programmation-java/web-services.ad @@ -213,10 +213,10 @@ public class ContactsWebService { @Produces( MediaType.APPLICATION_JSON ) public Contact getOne( @PathParam( "id" ) int id ) { return ...; } - @PUT + @POST @Consumes( MediaType.APPLICATION_JSON ) @Produces( MediaType.APPLICATION_JSON ) - public Contact create( FunkoPop pop ) { return ...; } + public Contact create( Contact modele ) { return ...; } @Path( "search" ) @GET @@ -231,7 +231,7 @@ Avec la classe précédente, le client pourra accéder aux urls : - `.../api/pop` en GET pour obtenir tous les Contacts, - `.../api/pop/34` en GET pour obtenir le Contact id:34, -- `.../api/pop` en PUT avec un Contact sérialisé en JSON pour créer un Contact, +- `.../api/pop` en POST avec un Contact sérialisé en JSON pour créer un Contact, - `.../api/pop/search?name=Toto` en GET pour obtenir les Contacts avec un nom donné. _Remarque: on peut injecter des EJB dans les WebServices_. diff --git a/formation-programmation-java/web-services.html b/formation-programmation-java/web-services.html index 9cb6e24..6dfe989 100644 --- a/formation-programmation-java/web-services.html +++ b/formation-programmation-java/web-services.html @@ -54,17 +54,17 @@ @Produces( MediaType.APPLICATION_JSON ) public Contact getOne( @PathParam( "id" ) int id ) { return ...; } - @PUT + @POST @Consumes( MediaType.APPLICATION_JSON ) @Produces( MediaType.APPLICATION_JSON ) - public Contact create( FunkoPop pop ) { return ...; } + public Contact create( Contact modele ) { return ...; } @Path( "search" ) @GET @Produces( MediaType.APPLICATION_JSON ) public List<Contact> search( @QueryParam( "name" ) String name ) { return ...; } }

Exemple

Avec la classe précédente, le client pourra accéder aux urls :

-
  • …​/api/pop en GET pour obtenir tous les Contacts,

  • …​/api/pop/34 en GET pour obtenir le Contact id:34,

  • …​/api/pop en PUT avec un Contact sérialisé en JSON pour créer un Contact,

  • …​/api/pop/search?name=Toto en GET pour obtenir les Contacts avec un nom donné.

+
  • …​/api/pop en GET pour obtenir tous les Contacts,

  • …​/api/pop/34 en GET pour obtenir le Contact id:34,

  • …​/api/pop en POST avec un Contact sérialisé en JSON pour créer un Contact,

  • …​/api/pop/search?name=Toto en GET pour obtenir les Contacts avec un nom donné.

Remarque: on peut injecter des EJB dans les WebServices.

Consommer un service web REST depuis une application Java EE

  • Décrire le service que l’on veut appeler dans une interface Java.

  • Demander à JAX-RS de créer un proxy d’appel vers le Web Service en précisant : — l’URL de base, — l’interface qui représente ce service.

Documentation ici

Dépendances Maven

Pour un serveur Wildfly 10, on ajoute :

<dependency>