Reading All Actions in Grails-Controller

I need to read all available actions from any controller in my web application. The reason for this is the authorization system, where I need to provide users with a list of allowed actions.

etc .: User xyz has authorization to perform the show, list, search actions. The user administrator has permission to perform actions, edit, delete, etc.

I need to read all the actions from the controller. Does anyone have an idea?

+6
grails grails-controller
source share
5 answers

This will create a list of cards (data variable) with information about the controller. Each item in the list is a map with a key controller corresponding to the name of the controller URL (for example, BookController β†’ "book"), the name of the controller corresponding to the class name ("BookController"), and the "actions" corresponding to the List of action names for this controller:

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 } 
+9
source share

Grails does not support an easy way to do this. However, I managed to assemble the puzzle from the available grails methods and came to this solution:

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

The grailsApplication variables and the controller name are introduced by grails. Since the controller itself does not have the necessary methods, this code retrieves its controllerClass (see GrailsControllerClass ), which has what we need: property uris and getMethodActionName method

+4
source share

Here is an example that works with Grails 2, i.e. it will capture actions defined as methods or closures

 import org.codehaus.groovy.grails.commons.DefaultGrailsControllerClass import java.lang.reflect.Method import grails.web.Action // keys are logical controller names, values are list of action names // that belong to that controller def controllerActionNames = [:] grailsApplication.controllerClasses.each { DefaultGrailsControllerClass controller -> Class controllerClass = controller.clazz // skip controllers in plugins if (controllerClass.name.startsWith('com.mycompany')) { String logicalControllerName = controller.logicalPropertyName // get the actions defined as methods (Grails 2) controllerClass.methods.each { Method method -> if (method.getAnnotation(Action)) { def actions = controllerActionNames[logicalControllerName] ?: [] actions << method.name controllerActionNames[logicalControllerName] = actions } } } } 
+4
source share

To print a list of all methods with action names:

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

I had to pull out a list of all the controllers and their corresponding URIs. This is what I did in the Grails 3.1.6 application.

 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()}" } } 
0
source share

All Articles