Odelia>Technologiesbeta

Scripts Groovy, actions, et services Grails

|

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 :

description = ' Premier test'
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>]

<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 :

class UrlMappings {
    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 :

data = {
        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 :

vue = {
        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 :

<html>
        <head/>
        <body>
                Salut tout le monde !<br/>
                - ${nom}
        </body>
</html>


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 :

class FeedService {

    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 :

items = {
        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.txt494 octets
test.groovy.txt71 octets
FeedService.groovy.txt162 octets
MashupController.groovy.txt1.44 Ko

balises dans Langages et systèmes

AJAX cajo Camel DSL Grails Groovy Java JBI prefuse RSS ServiceMix SOA