Reading out all actions in a Grails-Controller

前端 未结 5 537
别跟我提以往
别跟我提以往 2021-01-02 20:53

I need to read out all available actions from any controller in my web-app. The reason for this is an authorization system where I need to give users a list of allowed actio

相关标签:
5条回答
  • 2021-01-02 21:33

    Here's an example that works with Grails 2, i.e it will capture actions defined as either 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
                }
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-02 21:41

    This will create a List of Maps (the 'data' variable) with controller information. Each element in the List is a Map with keys 'controller', corresponding to the URL name of the controller (e.g. BookController -> 'book'), controllerName corresponding to the class name ('BookController'), and 'actions' corresponding to a List of action names for that 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
    }
    
    0 讨论(0)
  • 2021-01-02 21:41

    To print out a list of all the methods with action names:

       grailsApplication.controllerClasses.each {
                   it.getURIs().each {uri ->
                     println  "${it.logicalPropertyName}.${it.getMethodActionName(uri)}"
                   }
       }
    
    0 讨论(0)
  • 2021-01-02 21:42

    I had to pull a list of all controllers and their respective URI. This is what I did on a 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 讨论(0)
  • 2021-01-02 21:54

    Grails does not support a straightforward way to do this. However, I was able to put together a puzzle from available grails methods and have come 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) )
    }
    

    Variables grailsApplication and controllerName are injected by grails. As controller itself does not have necessary methods, this code retrieves its controllerClass (see GrailsControllerClass), which has what we need: property uris and method getMethodActionName

    0 讨论(0)
提交回复
热议问题