Dans cet article, nous discutons de l'idée de pouvoir invoquer du code Groovy, placé dans un fichier de script, comme si il s'agissait d'une action d'un contrôleur Grails ; ayant des fichiers scripts déployés dans une application Grails, nous montrons comment mettre en place un mécanisme simple qui permet d'exécuter du code Groovy au travers d'une URL formée en suivant une convention particulière.
De plus, nous montrerons comment autoriser l'utilisation de services Grails depuis un script.
Premier exemple
Prenons un exemple pour éclaircir cette idée ; voici le contenu d'un fichier script Groovy, test.groovy, déployé avec une application web Grails :
saluer = {
"Bonjour $params.nom !"
}
Pour invoquer le code de saluer, il suffit de naviguer vers l'URL :
http://<serveur>:<port>/<contexte>/mashup/test/saluer?nom=odelia
et le navigateur retourne le texte « Bonjour odelia ! ».
De manière identique, on peut également obtenir la valeur de la variable description, « Premier test », par l'URL :
http://<serveur>:<port>/<contexte>/mashup/test/description
Rendre accessible des données ou déclencher des actions ne peut être plus simple !
Convention d'URL et contrôleur MashupController
Comme vous pouvez le constater, l'URL doit suivre une convention de nommage particulière, de la forme générale :
http://<serveur>:<port>/<contexte>/mashup/<script>/<variable>[?<paramètres>]
où <script> représente le nom du script Groovy cible, et <variable>, la variable à lire ou à invoquer si cette variable est en fait une Closure.
C'est le contrôleur Grails MashupController, dont le code source est attaché à cet article, qui prend en charge le traitement de cette forme d'URL, à condition d'ajouter une entrée particulière dans le fichier UrlMappings.groovy de l'application Grails :
static mappings = {
"/$controller/$action?/$id?" {
constraints {
// apply constraints here
}
}
"500"(view:'/error')
"/mashup/$__scriptName/$__variableName"(controller: "mashup", action: "action")
}
}
L'implémentation de la classe MashupController s'appuie sur la classe Groovy GroovyShell pour évaluer les scripts et permet la résolution des variables autorisées dans l'écriture des scripts comme params ou mashup (voir ci-dessous).MashupController recherche un script dans un répertoire scripts situé dans le répertoire de l'application web.
Les exemples code qui suivent proviennent du fichier de script test1.groovy.
Utilisation de la méthode render
Vous pouvez utiliser l'appel mashup.render pour produire une réponse, tout comme vous le feriez avec la méthode render d'un contrôleur Grails.
L'exemple suivant permettra de générer une réponse en XML :
mashup.render(contentType: 'text/xml') {
livres {
livre(titre: 'GINA')
livre(titre: 'The Definitive Guide to Grails')
}
}
}
Il est aussi possible d'associer une vue GSP à une action scriptée :
mashup.render(view: 'vue', model: [nom: 'odelia'])
}
Dans ce cas, par convention, la classe MashupController recherchera le fichier vue.gsp dans le répertoire grails-app/views/mashup/script1.
Le contenu du fichier vue.gsp est repris ici :
Accéder à des services Grails par script
La classe MashupController peut aussi rendre des services Grails accessibles dans les scripts, au travers de variables prédéfinies à utiliser dans les scripts.
La méthode employée est que MashupController récupère les références vers les services de manière classique (par injection), et les associe aux variables prédéfinies.
Ainsi, dans le code de la classe, la variable feed est associée à une instance du service Grails FeedService.
Le service Grails FeedService est ainsi très simplement implémenté pour notre discussion :
boolean transactional = false
def readFeed(url) {
def rss = new XmlSlurper().parse(url)
rss.channel.item
}
}
La méthode readFeed se contente de collecter les éléments item d'un fil RSS dont l'URL est passé en argument.
Voici maintenant comment une action scriptée peut s'en servir pour générer une page web donnant la liste des cinq premiers titres du flux RSS de ce site web :
mashup.render(contentType: 'text/html', encoding: 'UTF-8') {
html {
body {
ul {
feed.readFeed('http://www.odelia-technologies.com/rss.xml')[0..4].each {
li(it.title.toString())
}
}
}
}
}
}
L'avantage majeur qu'il y a derrière cette possibilité d'exécuter des services Grails via des scripts, est que vous pouvez développer des services assez complexes, et les réutiliser facilement !
| Fichier attaché | Taille |
|---|---|
| test1.groovy.txt | 494 octets |
| test.groovy.txt | 71 octets |
| FeedService.groovy.txt | 162 octets |
| MashupController.groovy.txt | 1.44 Ko |