如果想測試Filter,可以繼承FilterTestCase, 這個類別可以使用一些由容器管理的物件,request、 response、config、filterChain可以分別取得HttpServletRequestWrapper、 HttpServletResponseWrapper、org.apache.cactus.server.FilterConfigWrapper (繼承自FilterConfig)與FilterChain物件。
直接來看個實例, 假設要撰寫一個可以過濾字元的Filter, 其中字元過濾清單可以由一個文字檔案設定。例如:
<	<
>	>
文字檔案會放在Web應用程式之中,並可在web.xml中設定Filter初始參數來告知檔案的路徑,你的Filter可能設計如 下:
package cc.openhome;
import java.io.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.*;
import javax.servlet.http.*;
public class CharacterFilter implements Filter {
    private Map<String, String> escapeMap;
    
    private class CharacterRequestWrapper extends HttpServletRequestWrapper {
        CharacterRequestWrapper(HttpServletRequest request) {
            super(request);
        }
        @Override
        public String getParameter(String name) {
            return doEscape(this.getRequest().getParameter(name));
        }
        private String doEscape(String parameter) {
            if(parameter == null) {
                return null;
            }
            String result = parameter;
            for(String origin : escapeMap.keySet()) {
                String escape = escapeMap.get(origin);
                result = result.replaceAll(origin, escape);
            }
            return result;
        }
    }
    
    public void init(FilterConfig filterConfig)
                  throws ServletException {
        BufferedReader reader = null;
        try {
            String escapeListFile = filterConfig
                        .getInitParameter("ESCAPE_LIST");
            reader = new BufferedReader(
                    new InputStreamReader(
                        filterConfig.getServletContext()
                            .getResourceAsStream(escapeListFile)));
            String input = null;
            escapeMap = new HashMap<String, String>();
            while ((input = reader.readLine()) != null) {
                String[] tokens = input.split("\t");
                escapeMap.put(tokens[0], tokens[1]);
            }
        } catch (IOException ex) {
            Logger.getLogger(CharacterFilter.class.getName())
                    .log(Level.SEVERE, null, ex);
        }
        finally {
            try {
                reader.close();
            } catch (IOException ex) {
                Logger.getLogger(CharacterFilter.class.getName())
                        .log(Level.SEVERE, null, ex);
            }
        }
    }
    public void doFilter(ServletRequest request, ServletResponse response,
              FilterChain chain) throws IOException, ServletException {
        HttpServletRequest requestWrapper =
                new CharacterRequestWrapper((HttpServletRequest) request);
        chain.doFilter(requestWrapper, response);
    }
    public Map<String, String> getEscapeMap() {
        return escapeMap;
    }
    public void destroy() {
    }
}
如果要對這個Filter進行測試,可以繼承FilterTestCase, 在這邊要測試的對象有兩個,一個是CharacterFilter的init()是否能正確載入文字檔案,生成過濾用的Map物件,另一個是測試 CharacterFilter的doFilter()後續元件,是否取得的請求參數都是經過濾的結果。以下是個測試案例的示範:
package test.cc.openhome;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.apache.cactus.FilterTestCase;
import org.apache.cactus.WebRequest;
import cc.openhome.CharacterFilter;
public class CharacterFilterTest extends FilterTestCase {
    static {
        System.setProperty(
                "cactus.contextURL", "http://localhost:8080/CactusExample");
    }
    
    private CharacterFilter filter;
    
    @Override
    protected void setUp() throws Exception {
        config.setInitParameter("ESCAPE_LIST", "/WEB-INF/escapelist.txt");
        filter = new CharacterFilter();
        filter.init(config);
    }
    
    public void testInit() throws Exception {
        Map<String, String> expected = new HashMap<String, String>();
        expected.put("<","<");
        expected.put(">",">");
        Map<String, String> result = filter.getEscapeMap();
        assertEquals(expected, result);
    }
    
    public void beginDoFilter(WebRequest req) {
        req.addParameter("param", "<test>test</test>");
    }
    
    public void testDoFilter() throws Exception {
        final String[] result = new String[1];
        FilterChain chain = new FilterChain() {
            @Override
            public void doFilter(ServletRequest req, ServletResponse resp)
                    throws IOException, ServletException {
                result[0] = req.getParameter("param");
            }
        };
        filter.doFilter(request, response, chain);
        assertEquals("<test>test</test>", result[0]);
    }
}
FilterTestCase 預設會請求/FilterRedirector,這要 對應一個作為Redirect proxy的Filter,你要於 web.xml中如下設定:
...
<filter>
<filter-name>FilterRedirector</filter-name>
<filter-class>org.apache.cactus.server.FilterTestRedirector</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterRedirector</filter-name>
<url-pattern>/FilterRedirector</url-pattern>
</filter-mapping>
...

