Grails: how to get controller by controller name in filter?

I have a filter and controllerName var get controller target.

For example: when a user tries to access /myApp/book/index , my filter starts and controllerName is equal to book . How can I get an instance of BookController?

Tks


EDIT:

I can get Artefact using:

 grailsApplication.getArtefactByLogicalPropertyName("Controller", "book") 

But what am I doing with this artifact?

+4
source share
4 answers

The controller will be registered as a spring bean. Just take it by name:

 applicationContext.getBean('mypackage.BookController') // or def artefact = grailsApplication.getArtefactByLogicalPropertyName("Controller", "book") applicationContext.getBean(artefact.clazz.name) 
+15
source

As Burt said, you probably don't need one controller instance inside the filter. This is the wrong way to solve your problem.

Grails controllers, which are automatically entered using the Spring Framework, have some black magic and procedures created when it was created. Therefore, I can assure you that this is not a way to solve this problem.

As you yourself described, you want to name your action, and I can imagine that you are trying to reuse some code that is in your action, perhaps to create some data in your database or even to work with your HTTP session , I'm right?

So, you can do two things to solve this problem.

1) Just redirect the request flow to your controller / action as follows:

 if (something) { redirect controller: 'xpto', action: 'desired' return false } 

2) Or you can get the logic inside your action (which does the dirty work you want to run), split this logic inside one service and reuse the service in both classes (action / service) as follows:

MyService.groovy

 class MyService { def methodToReuse() { (...) } } 

Mycontroller.groovy

 class MyController { def myService //auto-injected by the green elf def myAction = { myService.methodToReuse() } } 

MyFilters.groovy

 class MyFilters { def myService //auto-injected by the red elf (...) myService.methodToReuse() (...) } 

[] with,

+5
source

You should be able to call newInstance on the artifact found. newInstance works the same way as the constructor, so you can provide any parameters that you could use for a regular call to the constructor.

So you can just do:

 def bookController = grailsApplication.getArtefactByLogicalPropertyName("Controller", "book").newInstance() 
+2
source

Work code:

 import org.codehaus.groovy.grails.web.context.ServletContextHolder import org.codehaus.groovy.grails.web.servlet.GrailsApplicationAttributes import org.springframework.context.ApplicationContext ApplicationContext applicationContext = (ApplicationContext) ServletContextHolder.getServletContext().getAttribute(GrailsApplicationAttributes.APPLICATION_CONTEXT) def grailsApplication String nameController = "search" def artefact = grailsApplication.getArtefactByLogicalPropertyName("Controller", nameController) def controller = applicationContext.getBean(artefact.clazz.name) 
+1
source

All Articles