使用过滤器取消页面请求时,Grails会抛出404错误

时间:2012-03-27 07:59:43

标签: grails grails-filters

我有一个过滤器:

class MyFilters {
    def filters = {
        before = {
            render(view: "/test")
            return false
        }
    }
}

这在我使用控制器处理请求的页面上很有用,显示test.gsp的内容而不是我请求的页面。但是,当我尝试访问直接映射到GSP文件的页面时,出现404错误。

将渲染更改为简单render "test"会产生相同的结果,就像将其评论并离开return false一样。

3 个答案:

答案 0 :(得分:2)

Grails是一个MVC框架。如果您想将URL直接映射到GSP(无需通过控制器和操作进行重定向),您需要在UrlMappings.groovy内向Grails解释这一点。在那里你可以定义你的“快捷方式”。 E.g:

static mappings = {
    "/$viewName"(view:"/index") {
        constraints {
            viewName([some constraints])
        }
    }
}

这将在不通过控制器的情况下呈现views/index.gsp。如果您没有为这些URL定义控制器映射(或至少是视图映射),则不能使用grails过滤器:

如果你真的想拦截所有请求,你可以像这样在你的grails应用程序中添加一个servlet过滤器:

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");
    }
}

在此处,您可以根据applicationcontext和当前request进行重定向或渲染。

您需要将此过滤条件添加到web.xml。关于如何执行此操作,请查看:How do i use a servlet in my grails app?

答案 1 :(得分:0)

在我看来,你的应用正在做正确的事情。它显示404,因为 /views/test.gsp 不存在。当我将代码更改为以下内容时,它适用于我。

class MyFilters {
    def filters = {
        StackOverflowTestFilter (controller:'*') {
            before = {
                render("Hello World!")
                // also fine: render(controller:"mycontroller", action:"myaction")
                return false
            }
        }
    }
}

另外,您是否知道,返回false将始终取消剩余的流程?仅当过滤器注意到您要过滤的任何内容时,才会返回 false

希望这有帮助!

答案 2 :(得分:0)

您可以使用Grails渲染方法的状态参数轻松设置http状态代码

我没有使用过滤器对此进行测试,但在Grails控制器中使用beforeIntecerptors可以正常运行。

class MyFilters {
    def filters = {
        before = {
            render(view: "/test", status:200)
            return false
        }
    }
}