Servlets 为什么我的Servlet过滤器运行两次?

Servlets 为什么我的Servlet过滤器运行两次?,servlets,jakarta-ee,intellij-idea,servlet-filters,embedded-jetty,Servlets,Jakarta Ee,Intellij Idea,Servlet Filters,Embedded Jetty,我有一个简单的Servlet过滤器: package net.twentyonesolutions; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.Date; public class TestFilter implements Filter { public void doFilter(Servle

我有一个简单的Servlet过滤器:

package net.twentyonesolutions;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Date;

public class TestFilter implements Filter {

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        System.out.println(TestFilter.class.getSimpleName()       // line 12
                + " > "
                + ((HttpServletRequest)servletRequest).getRequestURL()
                + ": IP "+ servletRequest.getRemoteAddr()
                + "; at "
                + new Date().toString());

        // Pass request back down the filter chain
        filterChain.doFilter(servletRequest, servletResponse);    // line 20
    }

    public void init(FilterConfig filterConfig) throws ServletException {}

    public void destroy() {}
}
我将其添加到web.xml中,如下所示:

<filter>
    <filter-name>TestFilter</filter-name>
    <filter-class>net.twentyonesolutions.TestFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>TestFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
更新filterChain.toString 我在调用filterChain.doFilter之前添加了filterChain.toString的打印,它清楚地显示了差异

在第一次调用doFilter之前,filterChain中的第一个对象是my filter。请参见打印的两行:

TestFilter > fdvnqp1k0ut37fenee569vshqf http://localhost:8080/index.cfm: IP 0:0:0:0:0:0:0:1; at Tue Sep 06 09:59:09 PDT 2016
    ... filterChain: TestFilter->CFMLServlet@cdad6a3==lucee.debug.loader.servlet.CFMLServlet,1,true
TestFilter > fdvnqp1k0ut37fenee569vshqf http://localhost:8080/index.cfm: IP 0:0:0:0:0:0:0:1; at Tue Sep 06 09:59:09 PDT 2016
    ... filterChain: CFMLServlet@cdad6a3==lucee.debug.loader.servlet.CFMLServlet,1,true

我不确定该规范,但我希望在第一次调用TestFilter.doFilter之前,我的TestFilter会从链中删除,不是吗?

我认为问题在于您将WEB-INF/WEB.xml设置为默认描述符。因此web.xml将运行两次—一次设置默认值,一次作为发现的web-INF/web.xml—因此您将得到两个过滤器实例


如果您想知道默认值,请不要设置默认描述符或将其设置为null,但这样您就不会有默认servlet。

我认为问题在于您将WEB-INF/WEB.xml设置为默认描述符。因此web.xml将运行两次—一次设置默认值,一次作为发现的web-INF/web.xml—因此您将得到两个过滤器实例


如果您想知道默认值,请不要设置默认描述符或将其设置为null,但这样您就不会有默认servlet。

重定向?你看到两个请求,重定向从哪里来?如果是这样的话,为什么Servlet只被调用一次呢?为了进一步确认,我尝试了不同的属性。只有请求才会导致过滤器运行,这是我在使用简单的http GET请求访问服务器时所期望的。所有其他类型,即转发、包含和错误,根本不会触发筛选器。如果您否决此问题,请解释原因。至少它写得很清楚。你能展示你的嵌入代码吗?重定向?你看到两个请求,重定向从哪里来?如果是这样的话,为什么Servlet只被调用一次呢?为了进一步确认,我尝试了不同的属性。只有请求才会导致过滤器运行,这是我在使用简单的http GET请求访问服务器时所期望的。所有其他类型,即转发、包含和错误,根本不会触发筛选器。如果您否决此问题,请解释原因。至少它写得很清楚。你能展示你的嵌入代码吗?那么你的意思是调用webapp.setDescriptor而不是webapp.setDefaultDecriptor?谢谢你,Greg!感谢您创建Jetty项目:那么您的意思是调用webapp.setDescriptor而不是webapp.setDefaultDecriptor?谢谢您,Greg!感谢您创建码头项目:
TestFilter > fdvnqp1k0ut37fenee569vshqf http://localhost:8080/index.cfm: IP 0:0:0:0:0:0:0:1; at Tue Sep 06 09:59:09 PDT 2016
    ... filterChain: TestFilter->CFMLServlet@cdad6a3==lucee.debug.loader.servlet.CFMLServlet,1,true
TestFilter > fdvnqp1k0ut37fenee569vshqf http://localhost:8080/index.cfm: IP 0:0:0:0:0:0:0:1; at Tue Sep 06 09:59:09 PDT 2016
    ... filterChain: CFMLServlet@cdad6a3==lucee.debug.loader.servlet.CFMLServlet,1,true