6 votes

Lecture de toutes les actions dans un contrôleur Grails

Je dois lire toutes les actions disponibles de n'importe quel contrôleur dans mon application Web. La raison en est un système d'autorisation où je dois donner aux utilisateurs une liste d'actions autorisées.

Par exemple: L'utilisateur xyz a l'autorisation d'exécuter les actions afficher, lister, rechercher. L'utilisateur admin a l'autorisation d'exécuter les actions modifier, supprimer etc.

Je dois lire toutes les actions d'un contrôleur. Est-ce que quelqu'un a une idée?

9voto

Burt Beckwith Points 46122

Cela créera une liste de cartes (la variable 'data') avec des informations sur les contrôleurs. Chaque élément de la liste est une carte avec les clés 'controller', correspondant au nom d'URL du contrôleur (par exemple BookController -> 'book'), controllerName correspondant au nom de classe ('BookController'), et 'actions' correspondant à une liste de noms d'actions pour ce contrôleur:

import org.springframework.beans.BeanWrapper
import org.springframework.beans.PropertyAccessorFactory

def data = []
for (controller in grailsApplication.controllerClasses) {
    def controllerInfo = [:]
    controllerInfo.controller = controller.logicalPropertyName
    controllerInfo.controllerName = controller.fullName
    List actions = []
    BeanWrapper beanWrapper = PropertyAccessorFactory.forBeanPropertyAccess(controller.newInstance())
    for (pd in beanWrapper.propertyDescriptors) {
        String closureClassName = controller.getPropertyOrStaticPropertyOrFieldValue(pd.name, Closure)?.class?.name
        if (closureClassName) actions << pd.name
    }
    controllerInfo.actions = actions.sort()
    data << controllerInfo
}

6voto

Dónal Points 61837

Voici un exemple qui fonctionne avec Grails 2, c'est-à-dire qu'il capturera les actions définies à la fois comme des méthodes ou des closures

import org.codehaus.groovy.grails.commons.DefaultGrailsControllerClass
import java.lang.reflect.Method
import grails.web.Action

// les clés sont les noms logiques des contrôleurs, les valeurs sont des listes de noms d'actions
// appartenant à ce contrôleur
def controllerActionNames = [:]

grailsApplication.controllerClasses.each { DefaultGrailsControllerClass controller ->

    Class controllerClass = controller.clazz

    // sauter les contrôleurs dans les plugins
    if (controllerClass.name.startsWith('com.mycompany')) {
        String logicalControllerName = controller.logicalPropertyName

        // obtenir les actions définies comme méthodes (Grails 2)
        controllerClass.methods.each { Method method ->

            if (method.getAnnotation(Action)) {
                def actions = controllerActionNames[logicalControllerName] ?: []
                actions << method.name

                controllerActionNames[logicalControllerName] = actions
            }
        }
    }
}

4voto

OndrejM Points 81

Grails ne prend pas en charge un moyen simple de faire cela. Cependant, j'ai pu assembler un puzzle à partir des méthodes grails disponibles et en suis arrivé à cette solution :

def actions = new HashSet()
def controllerClass = grailsApplication.getArtefactInfo(ControllerArtefactHandler.TYPE)
                         .getGrailsClassByLogicalPropertyName(controllerName)
for (String uri : controllerClass.uris ) {
    actions.add(controllerClass.getMethodActionName(uri) )
}

Les variables grailsApplication et controllerName sont injectées par grails. Comme le contrôleur lui-même n'a pas les méthodes nécessaires, ce code récupère sa controllerClass (voir GrailsControllerClass), qui a ce dont nous avons besoin : la propriété uris et la méthode getMethodActionName

4voto

BZ. Points 1101

Pour imprimer une liste de toutes les méthodes avec des noms d'action:

   grailsApplication.controllerClasses.each {
               it.getURIs().each {uri ->
                 println  "${it.logicalPropertyName}.${it.getMethodActionName(uri)}"
               }
   }

0voto

Sanshila Points 158

J'ai dû extraire une liste de tous les contrôleurs et de leur URI respective. Voici ce que j'ai fait sur une application grails 3.1.6.

grailsApplication.controllerClasses.each { controllerArtefact ->
            def controllerClass = controllerArtefact.getClazz()
            def actions = controllerArtefact.getActions()
            actions?.each{action->
                def controllerArtefactString = controllerArtefact.toString()
                def controllerOnly = controllerArtefactString.split('Artefact > ')[1]
                println "$controllerOnly >>>> $controllerOnly/${action.toString()}"
            }
        }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X