我有一个当前定义为在呈现 View 后运行的过滤器:
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 中当前执行的一些信息,并且我想确保在请求完成后自己进行清理。我不想使用请求/ session 对象来打乱数据,因为我必须将它传递给我所做的所有调用;事实上,我有一个 Holder 类,我可以在 ThreadLocal 中查询值。
我需要自定义 MessageSource 中来自该 ThreadLocal 的信息。这就是我注意到
<g:message />
在 afterView
之后调用筛选。
最佳答案
您可以使用 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
直接接口(interface)。它也可以用 Groovy 编写,但我倾向于用 Java 编写过滤器,因为它们会为每个请求调用,而且 Groovy 增加的小开销可以在这里加起来。
关于Grails:有没有办法在 View 完全渲染后运行过滤器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14514954/