我需要从我的网络应用程序中的任何控制器中读出所有可用的操作。这样做的原因是授权系统,我需要向用户提供允许的操作列表。
例如为: 用户xyz具有执行操作show,list,search的权限。 用户admin具有执行操作编辑,删除等的授权。
我需要从控制器中读出所有动作。有没有人有想法?
答案 0 :(得分:9)
这将创建一个带有控制器信息的地图列表('data'变量)。 List中的每个元素都是一个带有键'controller'的Map,对应于控制器的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
}
答案 1 :(得分:5)
这是一个与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
}
}
}
}
答案 2 :(得分:4)
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注入。
由于控制器本身没有必要的方法,因此该代码检索其controllerClass(请参阅GrailsControllerClass),它具有我们所需的内容:property uris
和method getMethodActionName
答案 3 :(得分:4)
使用操作名称打印出所有方法的列表:
grailsApplication.controllerClasses.each {
it.getURIs().each {uri ->
println "${it.logicalPropertyName}.${it.getMethodActionName(uri)}"
}
}
答案 4 :(得分:0)
我必须提取所有控制器及其相应URI的列表。这是我在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()}"
}
}