Cet article est le premier de la série « Grails cette semaine » de l’année 2011, une série traduite à partir du la suite d’article « Grails This Week » de Burt Beckwith.
Dans cette traduction, j’ai décidé de garder la version originale des sections « Tweets Intéressants », « Jobs » et « Meetups »
Cette semaine a connu beaucoup d’activité avec plus de 20 plugins mis à jour et plusieurs offres d’emploi.
J’ai ajouté une nouvelle section pour les Meetups et les réunions des users group etc…. Je posterai tout ce que je trouverai, mais si vous organisez une session d’un user group, veuillez me contacter en avance pour être sûr de l’inclure dans la mise à jour de la semaine en question.
content-buffer version 1.0-RC1. Utilisez ce plugin pour ajouter des fragments de page aux sections prédéfinies dans votre modèle de layout
sendfile version 0.1. Permettre l’utilisation des fonctionnalités « sendfile » ou « X-sendfile » des serveurs web.
jquery-plugin-authoring version 1.0.1. Un template qui rend la création de plugin jQuery plus facile
weceem-spring-security version 1.0-RC1. Fournit les ingrédients nécessaires pour que le plugin Weceem puisse utiliser Spring Security pour l’autorisation et l’authentification.
Il y a eu beaucoup de plugins mis à jour:
activiti version 5.1. Intègre la suite BPM et le système de workflow d’Activiti
ajaxflow version 0.1.15. Permet de créer des Webflows Ajaxifiés
attachmentable version 0.2.0. Fournit une méthode générique pour ajouter et gérer les pièces jointes
batch-launcher version 0.4.2. Charger et lancer les applications Grails batch (ne sont pas des applications web)
jquery-validation version 1.7.3. Fournit les ressources de jQuery Validation, et dépend du plugin jQuery pour inclure la librairie.
jquery-validation-ui version 1.1.1. Validation côté client sans écrire du JavaScript
liquibase version 1.9.3.6. Refactoring de base de données LiquiBase
multi-tenant-core version 1.0.2. Permet d’exécuter multiples ‘clients’ (customers ou tenants en anglais) à partir d’une installation d’une application Grails
@recruithurst: #Grails#Developer large project for totally new international web site, you will need strong Grails and AGILE development experience London
L’année 2011 commence bien pour mon activité de blogueur autour des technologies de développement Web spécialement Java, Grails et Javascript (ExtJS).
J’ai en effet choisi de traduire la série des articles This Week In Grails rédigée par Burt Beckwith que je remercie au passage. Vous remarquerez que je n’ai pas traduit la section « Interresting Tweets » (tweets intéressants, et j’estime qu’il est plus logique de les laisser dans la langue originale) et la section « Jobs » (offres d’emploi autour de Grails).
Je m’attendais à ce que les choses soient plus lentes cette semaine à cause des vacances, mais il y a eu plusieurs articles liés à Grails.
A partir de cette semaine les articles de la série “Grails cette semaine” seront traduits dans des langages différents. Merci à Aitor Alzola pour la traduction Espagnole, Hu Jian pour la traduction Chinoise, Paulo Pereira pour la traduction Portugaise, et Nabil Adouani pour la traduction Française. N’hésitez pas à me contacter si vous êtes intéressés pour faire une traduction dans un autre langage.
Articles divers
L'ensemble des articles ci-dessous sont en anglais, leurs titres sont traduits.
codenarc version 0.8.1. Analyse statique de code pour Groovy
dynamic-domain-class version 0.2.1. Créer des classes de domaine dynamiquement en runtime
grails-melody version 0.9. Intègre le système de monitoring JavaMelody
jquery-validation-ui version 1.1. Validation côté client sans écrire de code JavaScript
multi-tenant-core version 1.0.1. Permet d’exécuter multiples ‘clients’ (customers ou tenants en anglais) à partir d’une installation d’une application Grails
Depuis quelque temps, je m’intéresse aux frameworks permettant la création d’interfaces web « riches » et plus particulièrement le Framework ExtJs qui est donc l’un des Framework RIA Javascript.
ExtJs est, pour moi, la meilleure librairie de sa catégorie, le plus complet en termes de composants graphiques et le mieux élaboré à mon sens. Certains préfèreraient dojo toolkit ou jQueryUI, notamment à cause de la licence commerciale d’ExtJs s’il est utilisé dans un projet ou une application propriétaire.
Aujourd’hui, dans le cadre du premier billet de cet article à 2 parties, je vais présenter un cas d’utilisation du Framework ExtJs avec le Framework Grails pour implémenter une simple liste de contacts. Dans le cadre de la deuxième partie, j’ajouterai le reste des fonctionnalités CRUD avec la gestion de validation.
Création de l’application Grails exemple
Il s’agit dans cet exemple de créer une application simple de gestion de contact. Commençons donc par créer l’application Grails.
grails create-app grails-extjs-contact
Ajoutons ensuite une classe de domaine Contact avec ses attributs et ses contraintes de validation
Listing 1 : définition de la classe de domaine Contact
Vérifions le fonctionnement de l’application Grails après la génération d’un contrôleur ContactController et des vues correspondantes avec la commande suivante
Pour ajouter le framework ExtJs dans le projet grails, commençons par télécharger la dernière version disponible (à ce jour c’est la version 3.2.1) à cette adresse http://www.sencha.com/products/js/thank-you.php?dl=extjs321. Une fois l’archive décompressée, copions le contenu de cette archive dans le dossier web-app/js de notre application grails.
Transformation de l’application Grails
Transformation du contrôleur ContactController
La première étape de cette transformation consiste à créer une vue grails-app/contact/index.gsp correspondant à l’action « index » du contrôleur ContactController. Ensuite, il faut enlever la redirection qui se trouve dans cette action du même contrôleur pour pouvoir afficher la vue et le fichier index.gsp
Dans ce dernier fichier, nous importons les fichiers nécessaires pour les librairies ExtJs et le fichier contact.js qui décrit le composant de type Grid responsable d’afficher de la liste des contacts.Voici le contenu du fichier index.gsp
Ajout de l’action « read » au controlleur ContactController
Cette action sera utilisée pour retourner la liste des contacts au format JSON attendu par le composant ExtJs. Nous pouvions modifier l’action « list » pour retourner du JSON, mais dans le cadre de cet exemple, nous allons garder le fonctionnement normal de l’action « list » générée par grails
Voici le contenu de l’action « read » dans ContactController
Listing 3 : code de l’action « read » du contrôleur ContactController
Cette action commence par récupérer les paramètres nécessaires pour la pagination (max et offset) et pour le tri des connées (order). Ensuite, un objet JSON est construit et renvoyé à la DataGrid côté client.
Ajout du fichier contact.js
Ce fichier contient le code javascript permettant la création d’un composant GridPanel, un composant graphique ExtJs permettant d’afficher une data grid.
Listing 4 : contenu du fichier contact.js qui décrit la création de la DataGrid des contacts
A la ligne 1 du listing 4, nous définissons un HttpProxy qui est un objet qui regroupe les urls à appeler pour chaque type de requête :
read : l’url de lecture
create : l’url de création de nouveau contact
update : l’url d’édition de contact existant
destroy : l’url de suppression de contact
Dans notre exemple, les urls sont spécifiées en chemin relatif à l’action courante
A la ligne 10 du listing 4, nous définissons un JsonReader qui est l’objet responsable d’interpréter la réponse du serveur. Dans le cas d’une requête de type « read » par exemple, le HttpProxy appelle l’action « read » du contrôleur ContactController qui renvoie le JSON suivant :
Ce JSON est interpreter donc par le JsonReader qui va créer un Record pour chaque element de la liste « data » en utilisant la définition des champs id, firstname, lastname, birthday, email, phone et address
A la ligne 26 du listing 4, nous définissions un JsonWriter qui sera responsable de construire les requêtes à envoyé au serveur dans le cas d’action d’écriture (create, update, destroy). Dans notre exemple, nous spécifions qu’il faut encoder les paramètres des requêtes et d’envoyer la valeur de tous les champs au serveur à chaque requête d’écriture, et non pas juste les champs modifiés.
A la ligne 31 du listing 4, nous définissons l’objet JsonStore qui sera utilisé par la DataGrid. Le store est la source de données. Remarquons que l’attribute « remoteSort » est à true, ce qui signifie que le le tri sera fait côté serveur
A la ligne 42 du listing 4, la DataGrid est définie avec les colonnes et leur bindings aux champs retournés par les JsonStore via le JsonReader. Le binding des colonnes est spécifié avec la propriété « dataIndex ».
Test de l’interface ExtJs développée
En accédant à l’url http://localhost:8080/grails-extjs-contact/contact/index nous obtenons une page contenant un GridPanel ExtJs listant les contacts et permettant d’effectuer tri des données et la pagination et l’actualisation de la liste. Nous pouvons aussi lire le nombre total des contacts de la base de données.
Conclusion
Dans ce billet, j’ai essayé de présenter comment se marient facilement les Frameworks Grails et ExtJs. C’est vrai qu’une connaissance de ce dernier est recommandée pour pouvoir bien manipuler cette intégration entre les deux Frameworks. Ceci dit, le code ExtJs reste très lisible et simple à comprendre.
Dans la deuxième partie de cet article, je reviendrai sur l’implémentation des autres actions du CRUD (Ajout, modification et suppression).
Les sources de l’application sont disponibles ici.
Le mardi 09 Février, s’est déroulée la réunion trimestrielle du pôle JAVA/J2EE organisée par mon entreprise Axones, dans un endroit convivial à Paris. C’était une occasion pour moi de retrouver mes collègues et d’échanger avec eux autours de sujets techniques et autres.
C’était aussi une occasion pour présenter une technologie, à laquelle j’ai commencé à m’intéresser depuis quelque mois. Il s’agit, en effet, du Framework Grails.
Ce billet me permet donc de partager avec vous, les « slides » de la présentation que j’ai pu effectuée en présence d’une trentaine de consultants JAVA/J2EE entre autres.
La présentation s’est bien déroulée, les principes de Grails ont suscité beaucoup d’intérêt, mais il y avait de multiples questions, surtout concernant:
le support de Groovy & Grails au niveau des environnements de développement
la performance des application Grails dans des environnements de production
Dans les prochains billets, je partagerai les démos que j’ai pu faire, avec des screencasts et les codes source.
Voici le premier article de mon blog, je le dédie à ma nouvelle passion, Groovy & Grails. Le choix du sujet de l’article s’est porté sur la transformation d’une simple application Grails, générée en scaffold statique, vers une application AJAX. Cette transformation se base sur les composants AJAX de Grails et sur le framework javascript jQuery (le choix de jQuery est tout simplement basé sur mes préférences, je pouvais aussi bien utiliser les autres Frameworks Javascript comme Prototype, scriptaculous).
Cadre de cet article
C’est un article destiné aux lecteurs ayant un minimum de connaissances autour de Grails. L’objectif n’étant pas d’introduire et d’expliquer comment marche Grails, mais de montrer une simple technique de transformation.
L’idéal serait que Grails permette de faire du scaffold AJAX, peut être que cet article introduirait cette idée si elle est jugée intéressante.
Etape 1 : Création des classes de domaines
Pour cette application, j’ai utilisé la version 1.2.0 de Grails et Spring Tools Suite 2.3.0.
L’exemple traité dans cet article est une application de gestion de produits organisés par catégorie.
Commençons donc par créer l’application gProducts en utilisant soit :
Les commandes Grails
grails create-app gProducts
L’environnement de développement STS
A partir de cette étape, les commandes Grails seront exécutées en utilisant la console Grails de l’environnement de développement STS comme suit :
Ensuite ajoutons deux classes de domaine Categorie et Produit
package fr.exemples.gproducts
class Produit {
String nom
String description
String image
float prix
static belongsTo = [categorie : Categorie]
static constraints = {
nom(blank:false)
description(blank:false)
image(nullable:true)
prix()
}
}
Listing 1 : code des classes de domain
Etape 2 : Création des contrôleurs et scaffold statique
Une fois que nos classes persistantes sont créées, il suffit de générer les contrôleurs Grails et les vues correspondantes en scaffold statique. Pour ce faire, il suffit d’exécuter les commandes de génération suivantes :
Ajoutons ensuite quelques données dans la base pour avoir un jeu de test. Pour cela, il faut modifier le fichier grails-app/conf/BootStrap.groovy comme suit :
import fr.exemples.gproducts.Produit
class BootStrap {
def init = { servletContext ->
def ordinateurs = new Categorie(nom : "Ordinateurs de bureau",
description : "Catégorie des ordinateurs de bureau.",
ordre:1,
image:"").save();
ordinateurs.save();
def portables = new Categorie(nom : "Ordinateurs portables",
description : "Catégorie des ordinateurs portables.",
ordre:2,
image:"");
portables.save();
def accessoires = new Categorie(nom : "Accessoires",
description : "Catégorie des accessoires pour ordinateur.",
ordre:3,
image:"");
accessoires.save();
new Produit (nom :"PACKARD BELL iMedia A4365 FR",
description:"PACKARD BELL iMedia A4365 FR",
image:"PACKARD_BELL_iMedia_A4365_FR.jpg",
prix:447,
categorie:ordinateurs).save();
new Produit (nom :"HP TouchSmart 300-1025fr",
description:"HP TouchSmart 300-1025fr",
image:"HP_TouchSmart_300-1025fr.jpg",
prix:750,
categorie:ordinateurs).save();
new Produit (nom :"ASUS EeeTop PC ET2002T-B0037 tactile",
description:"ASUS EeeTop PC ET2002T-B0037 tactile",
image:"",
prix:561,
categorie:ordinateurs).save();
new Produit (nom :"DELL Inspiron 1470-8471",
description:"DELL Inspiron 1470-8471",
image:"DELL_Inspiron_1470-8471.jpg",
prix:569,
categorie:portables).save();
new Produit (nom :"ASUS X70AC-TY033V",
description:"ASUS X70AC-TY033V",
image:"ASUS_X70AC-TY033V.jpg",
prix:499,
categorie:portables).save();
new Produit (nom :"Sony Netbook VAIO VPC-W11S1E/T",
description:"Sony Netbook VAIO VPC-W11S1E/T",
image:"Son_Netbook_VAIO_VPC-W11S1E_T.jpg",
prix:365,
categorie:portables).save();
}
def destroy = {
}
}
Listing 2 : Code de la class BootStrap
Nous pouvons par la suite tester l’application générée en exécutant la commande
Etape 3 : modification du layout et ajout des plugins nécessaires
Cette étape consiste à modifier le layout de la page pour avoir un menu à gauche permettant d’accéder aux interfaces de gestion des catégories et produits. Ce menu affichera aussi une liste de catégories permettant d’accéder rapidement aux produits correspondants.
Installation du plugin jQuery
Comme introduit au début de cet article, le framework Javascript qui sera utilisé est jQuery. Or ce dernier n’est pas supporté en natif dans Grails donc il faut passer par un plugin dédié : jQuery Plugin
Commençons par ajouter ce plugin en exécutant la commande Grails suivante :
grails install-plugin jquery
Ce plugin va permettre de transformer le code généré par les composants Grails de type AJAX (g:remoteLink, g:formRemote, g:submitToRemote) en utilisant le framework jQuery.
Au jour d’aujourd’hui, ce plugin est à la version 1.3.2.4
Modification du layout
Nous allons introduire dans le layout par défaut du scaffold, un menu à gauche de la page. Ce menu sera donc matérialisé par une page GSP partielle, nommée « _leftbar.gsp » dans le dossier « views/common ». L’appel à cette page se fait dans le layout principal, c’est-à-dire dans le fichier « views/layout/main.gsp », en utilisant la balise « g:render ».
Voici le contenu du fichier « main.gsp » après les modifications effectuées :
La ligne 7 du listing 3 montre l’appel au plugin jQuery. Cette balise permet d’indiquer à Grails d’utiliser le framework jQuery pour la génération du code Javascript pour effectuer les appels asynchrones.
La ligne 8 du listing 3 permet d’importer le fichier « gproducts.js » qui contient un ensemble de méthodes Javascript spécifiques à notre application.
Le contenu de ce fichier est le suivant et contient une méthode d’initialisation permettant de gérer l’affichage d’une indication, avant et après chaque appel AJAX. Cette méthode permet aussi de gérer le cas d’erreur dans les réponses AJAX:
Remarquons que sur la ligne 1 du listing 5, nous indiquons à Grails que dans cette GSP partielle, nous allons utiliser jQuery comme framework Javascript pour nos appels asynchrones. Ces derniers étant à générer pour toute les balises « g:remoteLink » de cette GSP.
L’attribut « update » renseigne sur le nom de l’élément HTML à mettre à jour avec les résultats des appels asynchrones, dans notre cas, il s’agit de la div ayant « body » comme id.
L’application est maintenant prête, nous pouvons tester la nouvelle fonctionnalité ajoutée. Lançons l’application et vérifions le résultat :
Nous remarquons dans cet écran une anomalie. En effet, un clic sur le menu « Catégories », fait un appel AJAX vers la liste des catégories. Le résultat de cette requête est affiché incluant un header et un footer. C’est tout à fait normal, il fallait changer le layout de page GSP de la liste des catégories. La même règle est à appliquer pour l’ensemble des vues générées par le scaffold statique de Grails, qui seront appelées en asynchrone.
Pour cela, nous allons créer une nouvelle page « ajax.gsp » dans « views/layout » et nous allons modifier le meta « layout » des différentes vues du scaffold.
Suite à ces modifications, la navigation en utilisant le menu à gauche s’effectue correctement :
Etape 4 : Transformation des liens HTML
Après l’ajout du plugin jQuery et la modification du layout, il reste maintenant à modifier :
les liens directs en liens invoquant des appels AJAX
les liens des colonnes de tri et les liens de pagination
les différentes actions des différents formulaires
Pour expliquer les modifications à apporter, nous allons se baser sur la gestion des catégories comme exemple. Les mêmes manipulations sont à apporter sur la gestion des produits.
Transformation des liens en liens invoquant des appels AJAX
Il s’agit des liens vers les pages de détails (pages de type show), des liens vers les formulaires de création et vers les pages de liste (à partir de la barre de navigation contextuelle).
Cette transformation est toute simple, il s’agit juste de remplacer les balises « g:link » par des balises « g:remoteLink » et renseigner l’attribut « update »
Prenons l’exemple de la page liste de catégories. Les liens à transformer sont :
Le lien « New Categorie » dans la barre de navigation qui se trouve au dessus de la liste
Les liens qui se trouvent dans la colonne « id » qui permettent d’afficher les détails d’une catégorie.
Après transformation, nous obtenons le code suivant :
Listing 9 : Modification du lien « Show Catégorie »
Il nous reste à appliquer les modifications sur le reste des balises « g:link » dans les différentes pages GSP de l’application.
N’oublions pas d’ajouter, dans toutes les pages ayant des liens à transformer, la balise suivante
Transformation des liens de tri et de pagination en pagination AJAX
Les liens de tri dans les colonnes des listes
Les colonnes triables utilisées dans les vues liste de catégories et liste de produits (générées par le scaffold) utilisent la balise « g:sortableColumn ». Cette balise permet de générer un lien HTML vers l’action de liste dans le contrôleur correspondant.
Pour générer des liens de type AJAX offrant cette fonctionnalité de tri, nous allons utiliser un nouveau plugin nommé : Remote Pagination. Ce plugin offre deux balises différentes :
util:remoteSortableColumn : créer des colonnes de tri en AJAX
util:remotePaginate : créer des colonnes de pagination en AJAX (sera utilisée dans le prochain paragraphe)
Nous commençons par installer le plugin :
grails install-plugin remote-pagination
Ensuite nous transformons les balises « g:sortableColumn » par « util:remoteSortableColumn » dans les pages de liste. Exemple pour la liste des catégories
Listing 10 : Modification des colonnes du tableau liste des catégories
Nous remarquerons que la balise « util:remoteSortableColumn » nécessite la spécification de l’action à exécuter dans le contrôlleur correspondant, et un attribut « update » qui renseigne sur l’élément HTML à modifier avec le résultat de l’appel AJAX.
N’oublions pas d’ajouter, dans toutes les pages ayant des liens à transformer, la balise suivante
Rappelons que cette balise est nécessaire pour utiliser jQuery pour effectuer les appels AJAX.
Nous pouvons maintenant tester le tri des colonnes des listes de catégories et de produits.
Pagination
Cette transformation est aussi simple que la précédente, il suffit d’utiliser la balise « util:remotePaginate » au lieu de la balise « g:paginate » en renseignant l’action à appeler dans le contrôleur en correspondant, ainsi que l’attribut « update ». Voici un exemple d’utilisation :
Listing 11 : Modification liens de pagination de la liste des catégories
Transformation des actions des formulaires
Les formulaires générés par le scaffold de Grails sont trois types :
Les formulaires de création: contiennent un seul bouton de submit
Les formulaires de consultation: contiennent deux boutons « edit » et « delete »
Les formulaires d’édition : contiennent deux boutons « update » et « delete »
Modification des formulaires de création
Les modifications à apporter aux formulaires de création sont simples. Il s’agit, en effet, de remplacer la balise « g:form » par la balise « g:formRemote » et renseigner les attributs suivants :
name : le nom du formulaire
update : l’id de l’élément HTML à mettre à jour avec le retour de l’appel AJAX
url : une map ayant un élément renseignant le nom de l’action à appeler dans le contrôleur correspondant
Voici la nouvelle déclaration du formulaire de création de catégorie
Les transformations à faire dans le cas de ce type de formulaire consistent à :
remplacer les balises g:actionSubmit par g:submitToRemote pour les deux boutons « edit » et « delete »
renseigner l’attribut « update » pour les deux boutons
renseigner l’attribut « id » pour les deux boutons, la valeur de cet attribut étant l’id de l’objet domaine en cours de consultation
remplacer l’événement « onclick » du bouton « delete » par l’attribut « before » comme suit :
before="if(!confirm('${message(code: 'default.button.delete.confirm.message', <strong>default</strong>: 'Are you sure?')}')) return false;"
L’attribut « before » correspond au code Javascript à exécuter avant l’appel AJAX. Dans notre cas, ce code correspond à demander une confirmation de suppression.
Voici l’exemple de transformation du formulaire de consultation d’une catégorie
Les dernières transformations concernent les formulaires d’édition. Ces transformations sont aussi simples que les précédentes :
transformer la balise « g:form » en « g:formRemote » en pointant l’action du formulaire sur l’action « update », en renseignant l’attribut « update » et en lui donnant un nom
garder le bouton « update » sans modification
transformer le bouton « delete » comme pour les formulaires de consultation
Voici l’exemple du formulaire d’édition d’une catégorie
Durant cet article, nous avons pu tester la transformation d’une application simple générée par Grails, en une application entièrement en AJAX en gardant les fonctionnalités de :
CRUD
Pagination
Tri des colonnes des listes
Validation des formulaires
Nous avons aussi pu utiliser deux plugins utilitaires :
jQuery plugin : pour utiliser jQuery comme framework javascript pour les routines AJAX
Remote Paginate plugin : pour effectuer la pagination et le tri en AJAX
J’espère que mon premier article est réussi et que l’idée soit considérée intéressante, en attendant d’autres articles autour de Grails.
Les sources de l’application sont disponibles ici.