Play Framework - Initiation - Partie 4
Au menu d’aujourd’hui
Nous allons voir comment :
- permettre à l’utilisateur de s’authentifier ou se déconnecter à partir de la page d’accueil
- permettre à l’utilisateur authentifié d’ajouter des informations (en
ajaxavecjQueryet en utilisantGSONde Google)
ATTENTION : la manière de coder utilisée dans ce tuto n’est pas forcément la plus appropriée. L’objectif étant de mettre les mains dans le cambouis de la façon la plus simple possible afin d’apprendre rapidement, ce n’est pas grave (ça c’est moi qui le dit). Gardez à l’esprit, qu’ensuite il va falloir faire travailler vos méninges pour faire plus pro.
PS : encore à propos du code, et tout particulièrment en ce qui concerne le javascript, je vais faire se pâmer certains, mais :
- je suis en train d’apprendre le js
- j’utilise les “options” les plus simples (compréhensibles rapidement)
- commentez, commentez !!! ça fait vivre le tuto et progresser tout le monde
- commentez “utile” ! (pourquoi, comment, …)
Et surtout bonne lecture
1) Ajout du mécanisme de connexion
Dans le controller Application.java :
Modifier le code de cette manière :
public class Application extends Controller {
//START : notre modification
@Before
static void setConnectedUser(){
if(Security.isConnected()){
User user = User.find("byFullname",Security.connected()).first();
renderArgs.put("user", user);
renderArgs.put("security",Security.connected());
}else {
renderArgs.put("user", new User("","","John Doe"));
}
}
//END
public static void index() {
List<Item> allItems = Item.findAll();
render(allItems);
}
}
Dans la vue index.html (views/Application/index.html)
Modifier le code de cette manière :
#{extends 'main.html' /}
#{set title:'Home' /}
<!--START : notre modification -->
Bonjour ${user.fullname} /
<a href="@{Secure.login()}">Login</a> /
<a href="@{Secure.logout()}">Logout</a>
<hr>
<!--END -->
<h1>Liste des liens</h1>
<ul>
#{list items:allItems, as:'anItem'}
<li><b>${anItem.label} : </b>${anItem.url} <i>(by ${anItem.author.fullname})</i></li>
#{/list}
</ul>
Lancez la bête !
Ouvrez l’url http://localhost:9000/

Clickez sur Login, authentifiez vous, paf ! on revient sur la page :

Vous êtes bien reconnu :) J’ai rarement vu plus facile pour gérer une connexion utilisateur (je n’ai même jamais du voir ça … peut-être avec Grails, il faudra que je vérifie)
2) Donner la possibilité d’ajouter des informations
C’est bien beau d’être authentifié, mais il faut que cela serve un chouilla.
Donc nous allons donner la possibilité aux utilisateurs authentifiés de pouvoir ajouter des liens et des bundles (catégories), et comme on est des Play!Champions, on va se le faire en “ajax”.
Play! arrive avec tout un lot de fonctionnalités, d’apis, de frameworks, dont jQuery, alors autant en profiter.
Nous allons dans un 1er temps créer un service bundles
Créer un controller “JSonBundles”
avec une méthode getList
package controllers;
import models.Bundle;
import play.mvc.Controller;
public class JSonBundles extends Controller {
public static void getList(){
renderJSON(Bundle.find(
"SELECT " +
"bundle.id, bundle.label " +
"FROM Bundle bundle").fetch());
}
}
Modifier routes :
on ajoute la ligne : GET /bundles.json JSonBundles.getList
appelez l’url http://localhost:9000/bundles.json et vous obtenez dans votre navigateur la sortie suivante :
[[1,"JavaScript"],[2,"HTML5"],[3,"Java"],[4,"MacOSX"],[5,"Mobiles"],[6,"Design"]]
Retourner dans la vue index.html (views/Application/index.html)
Alors nous allons faire un peu de jQuery.
- Nous allons construire l’IHM de saisie tout en jQuery (on pourrait faire du HTML, mais on s’entraine)
- le code n’est pas forcément élégant ni optimisé, mais c’est pour comprendre (ps: j’utilise l’attribut
id, je sais"cay mal", @mklabs, si tu me lis …) - l’IHM ne doit s’afficher que si on est authentifié
- l’IHM sera composé de : <!-- détailler ici -->
- nous allons “peupler” notre combobox avec la liste des bundles
- une fois que cela fonctionne nous verrons comment enregistrer nos liens en base
Ajout dans le code comme ci-dessous :
Remarque : il est inutile de faire une référence à jQuery dans notre page index.html car elle hérite de main.html (#{extends 'main.html' /}) où la référence est déjà faite.
#{extends 'main.html' /}
#{set title:'Home' /}
Bonjour ${user.fullname} / <!--/ ${security} -->
<a href="@{Secure.login()}">Login</a> /
<a href="@{Secure.logout()}">Logout</a>
<hr>
<h1>Liste des liens</h1>
<ul>
#{list items:allItems, as:'anItem'}
<li><b>${anItem.label} : </b>${anItem.url} <i>(by ${anItem.author.fullname})</i></li>
#{/list}
</ul>
<!-- c'est à partir d'ici que j'ajoute mon code -->
#{if security != null}
<!--Script chargé uniquement si utilisateur authentifié -->
<script type="text/javascript">
/*
je rajoute un div qui contiendra mes zones de saisie
oui, j'aurais pu faire un formulaire
*/
$('<div></div>').attr('id','inputthings').appendTo('body');
/*
j'ajoute une zone de texte
dans mon div inputthings
*/
$('<input type="text"/>')
.attr('id','label')
.attr('placeholder','saisir titre').width(360)
.appendTo('#inputthings');
$('<BR>').appendTo('#inputthings'); /* je saute une ligne */
/*
j'ajoute une 2ème zone de texte
dans mon div inputthings
*/
$('<input type="text"/>')
.attr('id','url')
.attr('placeholder','saisir lien').width(360)
.appendTo('#inputthings');
$('<BR>').appendTo('#inputthings'); /* je saute une ligne */
/*
j'ajoute une zone de texte de type textarea
dans mon div inputthings
*/
$('<textarea/>')
.attr('id','details')
.attr('placeholder','saisir détails').width(360).height(50)
.appendTo('#inputthings');
$('<BR>').appendTo('#inputthings'); /* je saute une ligne */
/*
j'ajoute une zone de liste
pour le choix du bundle
dans mon div inputthings
*/
$('<select><option value="default">Choisir un Bundle</option></select>')
.attr('id','bundles')
.appendTo('#inputthings');
/*
j'ajoute un bouton
qui me servira à publier les informations saisies
dans mon div inputthings
*/
$('<input type="submit"/>')
.attr('id','addLink')
.attr('value','Ajouter ...')
.click(
function(){
/* création d'un objet lien qui récupère les infos saisies */
var monlien = {
label:$('#label').attr('value'),
url:$('#url').attr('value'),
details:$('#details').attr('value'),
bundle:{
id:$('#bundles').attr('value'),
label:$('#bundles option:selected').text()
}
}
/* affichage de l'objet dans la console pour vérification*/
console.log(monlien);
}
)
.appendTo('#inputthings');
/*--------------------------------------*/
/* C'EST ICI QUE CA DEVIENT INTERESSANT */
/*--------------------------------------*/
/*
je fais une requête ajax qui appelle mon service bundles.json
avec les données obtenues, je "peuple" ma liste de choix
*/
$.ajax({ cache: false,
type: "GET",
url: "/bundles.json",
dataType: "json",
error: function () {
alert("oups, y'a un pb !");
},
success: function (data) {
var maliste = $('#bundles')[0];
$.each(data,function(){
var option = new Option(this[1], this[0]);
maliste.add(option);
});
}
});
</script>
#{/if}
- dans le navigateur : http://localhost:9000/
- s’authentifier : magique : le formulaire de saisie apparaît
- saisir des infos (on s’aperçoit que la zone de liste contient bien nos bundles), clicker sur le bouton
- afficher la console du navigateur (j’avais oublié, il vaut mieux être sous safari ou chrome, désolé pour les autres, en même temps vous pouvez remplacer
console.logparalert) - normalement vous avez ceci :

Trop bien, allez on continue.
Ajouter les données en base
Nous allons donc modifier le controller Items (pas JSonItems) car il est sécurisé (@With(Secure.class)) et que seuls les utilisateurs authentifiés peuvent faire des ajouts en base.
a) 1er ajout de code dans Items.java
public static void addItem(String item){
renderJSON(item);
}
en gros, quand on appellera notre service, cela nous retournera ce que l’on a passé en paramètre (ça sert à rien, mais c’est pour vérifier)
b) ajout d’une route dans routes :
Ajouter ceci :
POST /items.auth.json.add Items.addItem
c) modification du code js de index.html :
Dans le code du click du bouton, modifier le code de la façon suivante :
$('<input type="submit"/>')
.attr('id','addLink')
.attr('value','Ajouter ...')
.click(
function(){
/* création d'un objet lien qui récupère les infos saisies */
var monlien = {
label:$('#label').attr('value'),
url:$('#url').attr('value'),
details:$('#details').attr('value'),
bundle:{
id:$('#bundles').attr('value'),
label:$('#bundles option:selected').text()
}
}
/* affichage de l'objet dans la console pour vérification*/
console.log(monlien);
/*---------------------*/
/* NOTRE AJOUT EST ICI */
/*---------------------*/
/*
1-on fait une requête de type POST
2-on appelle notre service
3-on lui passe notre objet monlien de façon "jsonisée"
4-si tout va bien, on voit les données retournées
par le serveur dans la console
*/
$.ajax({ cache: false,
type: "POST",
url: "/items.auth.json.add",
data:{item:JSON.stringify(monlien)},
error: function () {
alert("oups, y'a un pb !");
},
success: function (dataFromServer) {
/* affichage des données retournées */
console.log(dataFromServer);
}
});
}
)
.appendTo('#inputthings');
- dans le navigateur : http://localhost:9000/
- s’authentifier : magique : le formulaire de saisie apparaît
- saisir des infos , clicker sur le bouton
- afficher la console du navigateur
- normalement vous avez ceci :

Les données ont bien été envoyées au serveur, qui nous a bien répondu. Il nous reste donc à enregistrer tout ça en base.
d) modification du controller Items pour persister les données en base :
Nous allons utiliser GSON de Google (embarqué avec Play!) pour retransformer notre string en un objet Item :
public static void addItem(String item){
JsonObject o = new JsonObject();
/* penser à :
- import com.google.gson.JsonObject;
- import com.google.gson.Gson;
*/
Gson gson = new Gson();
Item anItem = new Item();
anItem = gson.fromJson(item,Item.class);
anItem.author = User.find("byFullname",Security.connected()).first();
anItem.save();
renderJSON(anItem);
}
- dans le navigateur : http://localhost:9000/
- saisir des infos , clicker sur le bouton
- afficher la console du navigateur
- normalement vous avez ceci :

Oups! I did it again, mot de passe est en clair, mais on peut voir que cela fonctionne
- recharger la page

Notre nouvelle saisie apparaît !
e) une dernière retouche
Dans le controller Items supprimer renderJSON(anItem);
Dans index.html, dans le code qui fait la requête ajax lors du click du bouton, on va faire quelque chose de bien “dirty” : nous ajoutons le code window.location.reload(); pour forcer le rechargement de la page (maintenant vous avez tout ce qu’il faut pour “ajaxifier” l’affichage des liens, un peu à vous de bosser les gars !).
$.ajax({ cache: false,
type: "POST",
url: "/items.auth.json.add",
data:{item:JSON.stringify(monlien)},
error: function () {
alert("oups, y'a un pb !");
},
success: function (dataFromServer) {
/* affichage des données retournées */
//console.log(dataFromServer);
window.location.reload();
}
});
- dans le navigateur : http://localhost:9000/
- saisir des infos , clicker sur le bouton
- afficher la console du navigateur
- normalement ça fonctionne
PS: si vous envoyez des données vides ça “plante”, pensez à rajouter un peu de code …
Maintenant, vous avez tout ce qu’il faut, faudra coder plus propre et plus élégant que moi.


Recent comments
1 year 50 weeks ago
1 year 50 weeks ago
1 year 51 weeks ago
1 year 51 weeks ago
1 year 51 weeks ago
1 year 51 weeks ago
1 year 51 weeks ago
1 year 51 weeks ago
1 year 51 weeks ago
1 year 51 weeks ago