我有一个过滤器,当前定义为在渲染视图后运行:
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
的方式。
答案 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添加的小开销可以在这里加起来。