1

我有一个当前定义为在呈现视图后运行的过滤器:

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

4

1 回答 1

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 添加的小开销可以在这里加起来。

于 2013-01-25T04:18:04.220 回答