2010-06-02 7 views
6

Muszę odczytać wszystkie dostępne akcje z dowolnego kontrolera w mojej aplikacji internetowej. Powodem tego jest system autoryzacji, w którym muszę podać użytkownikom listę dozwolonych działań.Odczytywanie wszystkich operacji w Grails-Controller

Np .: Użytkownik xyz ma uprawnienia do wykonywania akcji Pokaż, listy, wyszukiwania. Użytkownik ma uprawnienie do wykonywania akcji edycji, usuwania itp.

Muszę odczytać wszystkie czynności z kontrolera. Czy ktoś ma pomysł?

Odpowiedz

9

Spowoduje to utworzenie listy map (zmienna "dane") z informacjami kontrolera. Każdy element na liście jest mapą z kontrolerem kluczy, odpowiadającą nazwie URL kontrolera (np. BookController -> "książka"), controllerName odpowiadającej nazwie klasy ("BookController") i "działaniom" odpowiadającym Lista nazw akcji dla tego kontrolera:

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

czy ten kod nadal pracować z Grails 2? Mam na myśli, że w Grails2 kontrolery nie są już zamknięciami. – fabien7474

+3

Zamknięcia są nadal obsługiwane, ale preferowane są metody. I 2.0 można wyszukiwać metod za pomocą adnotacji @ grails.web.Action –

+0

@BurtBeck z Czy możemy uzyskać przedInterceptor od używania klas ControllerClasses? – user1791574

4

Grails nie obsługuje prostego sposobu na zrobienie tego. Jednak udało mi się ułożyła puzzle z dostępnych metod Grails i doszli do tego rozwiązania:

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

Zmienne grailsApplication i controllerName są wstrzykiwane przez Grails. jako kontroler sam nie posiada niezbędnych metod, ten kod pobiera jej controllerClass (patrz GrailsControllerClass), który ma co potrzebujemy: własność uris i sposobu getMethodActionName

4

Oto przykład, który współpracuje z Grails 2, czyli będzie to uchwycić działań określonych albo jako metod lub zamknięć

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

Aby wydrukować listę wszystkich metod z nazwami Działanie:

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