读出 Grails-Controller 中的所有操作

Posted

技术标签:

【中文标题】读出 Grails-Controller 中的所有操作【英文标题】:Reading out all actions in a Grails-Controller 【发布时间】:2011-02-26 17:31:47 【问题描述】:

我需要从我的网络应用程序中的任何控制器读取所有可用操作。这样做的原因是一个授权系统,我需要给用户一个允许操作的列表。

例如: 用户 xyz 具有执行 show、list、search 操作的权限。 用户 admin 具有执行编辑、删除等操作的权限。

我需要从控制器读出所有动作。有人有想法吗?

【问题讨论】:

【参考方案1】:

这将创建一个包含控制器信息的地图列表(“数据”变量)。 List 中的每个元素都是一个 Map,键为 'controller',对应于控制器的 URL 名称(例如 BookController -> 'book'),controllerName 对应于类名('BookController'),'actions' 对应于该控制器的动作名称列表:

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

【讨论】:

这段代码是否仍然适用于 Grails 2?我的意思是,在 Grails2 中,控制器不再是闭包了 仍然支持闭包,但首选方法。 I 2.0 可以搜索带有@grails.web.Action 注解的方法 @BurtBeckwith 我们可以通过使用 controllerClasses 获得 beforeInterceptor 吗?【参考方案2】:

这是一个适用于 Grails 2 的示例,即它将捕获定义为方法或闭包的操作

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
            
        
    

【讨论】:

【参考方案3】:

Grails 不支持直接执行此操作的方法。但是,我能够从可用的 grails 方法中拼凑出一个难题,并得出了这个解决方案:

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

变量 grailsApplication 和 controllerName 由 grails 注入。 由于控制器本身没有必要的方法,这段代码检索它的控制器类(见GrailsControllerClass),它有我们需要的:属性uris和方法getMethodActionName

【讨论】:

【参考方案4】:

要打印出带有动作名称的所有方法的列表:

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

【讨论】:

【参考方案5】:

我必须提取所有控制器及其各自 URI 的列表。这就是我在 grails 3.1.6 应用程序上所做的。

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

【讨论】:

以上是关于读出 Grails-Controller 中的所有操作的主要内容,如果未能解决你的问题,请参考以下文章

数据流中的中位数

一个关于在VB中将Recordset 读出的内容放到一个数组变量中的问题!!

数据流中的中位数

用vc++,如何读出设备信息,入cpu,内存,分区,各个分区的剩余空间等?

数据流中的中位数

64 数据流中的中位数