I think the short, general form of my question might be the best: How do I get Grails/Spring to "see" dependency library components, including filters and servlets that are not Grails controllers?
Here are the specifics:
I'd like to use the Togglz feature toggle library (v2.0.1) in my Grails (v2.4.4) application. Togglz comes with its own web console servlet and a TogglzFilter class that does some initialization at start-up and sets per-request state. In a vanilla spring web app, both of these are normally wired by annotations, so the url path [context-root]/togglz/index
invokes the console. (The server is Pivotal tc/tomcat 7, which I believe satisfies the Servlet 3.0 requirement for the annotation-driven configuration to work.) My question is, how do I wire such a thing into my Grails application?
I'm new to both Grails and Togglz, so I'm probably missing something stupid. All the things I've tried produce a 404 on the console URL. So far, I have:
- Added the togglz core, servlet, console, and spring dependencies in BuildConfig.groovy.
- Added org.togglz and the package where I put my Togglz config (next two items) to the value of grails.spring.bean.packages in Config.groovy.
- Created classes FeatureTogglz and FeatureTogglzConfig, both annotated with @Component.
That seemed like it should do it, but when it didn't, I tried a few more things:
- Searching various combinations of Grails, Togglz, Library, Servlet, Filter, etc. produced two near misses:
- In this thread, someone else was having trouble getting Grails to load Togglz. They were seeing not-found errors on start-up where I don't, and they were concerned with the actual applying of the togglz, not the console servlet. Also, the answer in that case was to remove the
metadata-complete
attribute from web.xml. My project has no web.xml at all. - In this thread, someone wanted to put a filter after a non-controller based response. In my case, activating the filter itself is the problem, not what kind of request/response it guards.
- In this thread, someone else was having trouble getting Grails to load Togglz. They were seeing not-found errors on start-up where I don't, and they were concerned with the actual applying of the togglz, not the console servlet. Also, the answer in that case was to remove the
Attempted a UrlMappings.groovy entry using the console servlet class as the target:
"/togglz/index"(org.togglz.console.TogglzConsoleServlet)`.
I don't see any examples like this; I was just trying to guess what might accomplish what would otherwise be in web.xml.
Thinking maybe the problem was that Grails wasn't setting up the Togglz filter, which does some initialization at start-up in addition to setting the context for each request, I created conf/TogglzFilters.groovy, again guessing at the content:
import org.togglz.servlet.TogglzFilter public class TogglzFilters { def filters = { togglzFilter(controller:'*', action:'*') { before = { new TogglzFilter().doFilter(request, response, null) } } } }
Even before it null-pointed, this felt totally wrong because what I want is to have Grails use the provided filter, not code it myself. But all the filter examples I could find used inline code.
As I said, much of this is new to me, so if I've just missed something I should have studied, I'd be as grateful for a pointer as for a direct answer.
Thanks.
So there are two aspects to your question that have to be addressed.
First, the Spring configuration based on annotations.
Spring annotations from within the
org.springframework.context.annotation
package, such as@Configuration
or even just@Bean
won't be identified by Grails unless you tell it which packages to scan. This is done from within yourConfig.groovy
with the following line:In the above example my Spring components are in the package
the.package.name.goes.here
so you will need to update that with the packages for your components. You can specify multiple packages since the setting is aList
ofString
s.Secondly, installing the servlet filter from your library. Now, this can be done any number of ways, from writing a plugin to do so for you, or installing it manually (which I will cover here).
To begin installing the servlet filter you first need to use install templates command to copy the templates used by Grails during code generation to your project. These templates will appear under
src/templates
. In this case we need to modifysrc/templates/war/web.xml
to include the servlet filter.Typically installing a filter looks something like the following:
The exact requirements and settings for your servlet filter may differ slightly and I recommend you refer to the documentation for your library for them.
With the two above changes to your Grails application you should be able to leverage both the Spring annotation based configuration and servlet filter provided by your library.
Good luck and happy holidays!