Grails:在完全呈现视图后,有没有办法运行过滤器?

时间:2013-01-25 03:40:15

标签: grails

我有一个过滤器,当前定义为在渲染视图后运行:

class MyFilter {
  def filters = {
    doStuff(controller: '*', action: '*') {
      before = {...}
      after = {...} 
      afterView = { 
        // code I want to run when EVERYTHING is set and done }
        Holder.setCurrentData(null)
    }
  }
}

这应该有效,但我注意到<g:message />过滤后执行了afterView个标签(可能是其他标签;这是我感兴趣的标签)。

这是一个问题,因为我使用此过滤器来跟踪ThreadLocal中当前执行的一些信息,我想确保在请求完成后我自己清理。我不想使用请求/会话对象来随机播放数据,因为那时我必须将它传递给我所做的所有调用;实际上,我有一个Holder类,我可以查询ThreadLocal中的值。

我需要自定义MessageSource中来自ThreadLocal的信息。这就是我注意到在<g:message />过滤器之后调用afterView的方式。

1 个答案:

答案 0 :(得分:2)

您可以使用servlet过滤器:

package com.mycompany

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.springframework.web.filter.GenericFilterBean;

public class MyFilter extends GenericFilterBean {

   public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {

      try {
         chain.doFilter(req, res);
      }
      finally {
         Holder.setCurrentData(null);   
      }
   }
}

如果您还没有运行grails install-templates,那么您可以在src / templates / war / web.xml中注册它,如下所示:

<filter>
   <filter-name>myFilter</filter-name>
   <filter-class>com.mycompany.MyFilter</filter-class>
</filter>

<filter-mapping>
   <filter-name>myFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

我为了方便而扩展了GenericFilterBean,但你也可以直接实现javax.servlet.Filter接口。它也可以用Groovy编写,但我倾向于用Java编写过滤器,因为它们是为每个请求调用的,Groovy添加的小开销可以在这里加起来。