2013-01-25 54 views
1

我有一個當前定義的運行圖之後被渲染過濾器: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過濾器之後調用的。

回答

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 /模板/戰爭/像這樣的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添加的小額開銷可以在此處添加。

+0

此解決方案正常工作。我對Grails沒有更好的處理方式感到失望,這感覺就像「滾動你自己」。你知道爲什麼'afterView'過濾器不能運行一旦視圖完全呈現,標籤和所有? –

+0

Grails過濾器包裝Spring'HandlerInterceptor's,因此它們僅限於攔截控制器請求而不是靜態資源請求,並且也只有與「HandlerInterceptor」相同的回調。 –

+0

謝謝。這解釋了它。 –