0

带有ServletFilter的嵌入式 Tomcat 的简单实例:

            Tomcat tomcat = new Tomcat();
            Context rootCtx = tomcat.addContext("", base.getAbsolutePath());
            FilterDef filterDefinition = new FilterDef();
            filterDefinition.setFilterName(URLFilter.class.getSimpleName());
            filterDefinition.setFilterClass(URLFilter.class.getName());
            rootCtx.addFilterDef(filterDefinition);

            FilterMap filter1mapping = new FilterMap();
            filter1mapping.setFilterName(URLFilter.class.getSimpleName());
            filter1mapping.addURLPattern("/*");
            rootCtx.addFilterMap(filter1mapping);

            Tomcat.addServlet(rootCtx, "Servlet1", new Servlet1());
            rootCtx.addServletMapping("/Servlet1", "Servlet1");

URL过滤器实现:

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
    Boolean filtered = false;
    System.out.println("request intercepted");
    if (request.getAttribute("filtered") != null) {
        filtered = true;
        request.setAttribute("filtered", filtered);
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        httpResponse.sendRedirect("/Servlet1");
        return;
    } else {
        filterChain.doFilter(request, response);
    }
}

由于某种原因,这最终陷入了无限循环,并且永远不会到达 Servlet1。实现 URL 过滤器的正确方法是什么,以便我可以在传递响应之前仔细检查请求周围的参数?

4

2 回答 2

1

查看sendRedirect()的 JavaDocs 。您在每个请求上告诉客户端返回到 /Servlet1,但随后您将无限期地过滤它。在某些时候,您需要停止在过滤器中发送重定向!

再澄清一些。如果您不打算主动过滤请求,您唯一需要做的就是调用

filterChain.dofilter(request, response);

除非您真的要发送 HTTP 302(临时重定向),否则不要发回重定向。Servlet 过滤器链是 servlet 进程的重要组成部分,尽管它可能看起来违反直觉,但您可以通过调用 filterChain.doFilter 命令使您的过滤器看起来什么都不做,这允许请求继续到您配置的其他过滤器应用服务器。

我不清楚的是过滤您的过滤器试图做什么。如果您打算按 URL 过滤,则应查找匹配的 URL,然后仅在匹配时才重定向。

于 2014-03-27T14:54:21.377 回答
0

由于这解决了您的问题,因此将其发布为答案。

首先,您需要确保您是沿着应用程序过滤器链传递请求,或者您正在重定向它:

@Override
public void doFilter(ServletRequest request, ServletResponse response,
    FilterChain filterChain) throws IOException, ServletException {

    Boolean filtered = false;
    System.out.println("request intercepted");
    if (!filtered) {
        filtered = true;
        ((HttpServletResponse) response).sendRedirect("/Servlet1");
        return;
    }

    filterChain.doFilter(request, response);
}

然后您需要确保过滤器知道传入请求何时已经被重定向,以便它不会再次重定向它:

@Override
public void doFilter(ServletRequest request, ServletResponse response,
    FilterChain filterChain) throws IOException, ServletException {

    Boolean filtered = false;
    System.out.println("request intercepted");
    if (request.getAttribute("filtered") != null) {
        filtered = (Boolean) request.getAttribute("filtered");
    }

    if (!filtered) {
        request.setAttribute("filtered", Boolean.TRUE);
        ((HttpServletResponse) response).sendRedirect("/Servlet1");
        return;
    }

    filterChain.doFilter(request, response);
}
于 2014-03-27T15:53:30.747 回答