【问题标题】:Grails throws a 404 error when canceling a page request with a filterGrails 在使用过滤器取消页面请求时抛出 404 错误
【发布时间】:2012-03-27 07:59:43
【问题描述】:

我有一个过滤器:

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

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

将渲染更改为简单的 render "test" 会产生相同的结果,就像将其注释掉并留下 return false 一样。

【问题讨论】:

    标签: grails grails-filters


    【解决方案1】:

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

    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?

    【讨论】:

    • 我应该澄清一下。我通常不会重定向到/test.gsp,仅在某些情况下,这就是为什么需要使用过滤器而不是 URL 映射来完成它(除非有办法进行条件映射?)
    • 你有什么样的限制?是与数据库相关还是一些静态约束?
    • 我检查的内容与问题无关。不做任何检查就存在问题。
    • 如果没有控制器,过滤器将不会被调用。如果没有到“虚拟”控制器的 urlmapping 或手动编写容器过滤器,您将无法完成。
    • 我猜是因为答案只是编辑而不是新的,我不会收到赏金吗?但是,如果有任何不清楚的地方,请告诉我 :-)
    【解决方案2】:

    在我看来,您的应用正在做正确的事情。它显示 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

    希望这会有所帮助!

    【讨论】:

    • /views/test.gsp 确实存在。当我在通过控制器生成的页面上使用相同的过滤器时,它显示正常,但是在通过 GSP 生成的页面上,我得到了奇怪的 404 错误。
    • 另请注意,仅在过滤器中执行 render "test" 也会产生 404 错误。好像和return false有关。
    • 您尝试过我发布的代码吗?它返回 false 并呈现 Hello World - 所以绝对不是这样。我还注意到您没有在示例中定义过滤器名称和范围(在我的示例中为stackOverflowTestFilter (controller:'*'))。看着the Grails documentation,看来你必须提供。
    【解决方案3】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-11
      • 1970-01-01
      • 2013-02-22
      • 2010-11-30
      • 2017-07-07
      • 2017-02-27
      • 2011-10-24
      相关资源
      最近更新 更多