Grails throws 404 error when canceling filter page request
I have a filter:
class MyFilters {
def filters = {
before = {
render(view: "/test")
return false
}
}
}
This works great on pages where I use a controller to handle the request, showing the content of test.gsp instead of the requested page. However, when I try to access a page that maps directly to the GSP file, I get a 404 error.
Changing the render just render "test"
gives the same results as commenting out and just leaving return false
.
source to share
Grails is an MVC framework. If you want to map url directly to GSP (no redirection through controller and action) you need to explain this grails inside your UrlMappings.groovy
. There you can define your "labels". For example:.
static mappings = {
"/$viewName"(view:"/index") {
constraints {
viewName([some constraints])
}
}
}
Will be displayed views/index.gsp
without going through the controller. If you are not defining a controller mapping (or at least a view mapping) for these urls, you can NOT use grails filters:
If you really want to intercept ALL requests, you can add a servlet filter to your grails app like this:
import javax.servlet.*
import org.springframework.web.context.support.WebApplicationContextUtils;
class TestFilter implements Filter {
def applicationContext
void init(FilterConfig config) throws ServletException {
applicationContext = WebApplicationContextUtils.getWebApplicationContext(config.servletContext)
}
void destroy() {
}
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("this filter has been called");
}
}
Here you can perform redirects or rendering based on applicationcontext
and current request
.
You need to add this filter to yours web.xml
. For how to do this, see: How do I use a servlet in my grails application?
source to share
It seems to me that your application is working correctly. It shows 404 because /views/test.gsp doesn't exist. When I change the code to the following, it works for me.
class MyFilters {
def filters = {
StackOverflowTestFilter (controller:'*') {
before = {
render("Hello World!")
// also fine: render(controller:"mycontroller", action:"myaction")
return false
}
}
}
}
Also, did you know that returning false will always cancel the rest of the thread? Return false only if the filter detects some violation of what you want to filter.
Hope this helps!
source to share