如何让 servlet 过滤器在 Tomcat 中的应用程序启动时停止加载?

Posted

技术标签:

【中文标题】如何让 servlet 过滤器在 Tomcat 中的应用程序启动时停止加载?【英文标题】:How do I get servlet filters to stop loading on application startup in Tomcat? 【发布时间】:2011-03-31 00:11:04 【问题描述】:

下面是我的部署描述符。我正在使用 Spring MVC,但我有一个应该运行的 url 重写过滤器,然后转发到相应的控制器。由于某种原因,此过滤器在启动时加载,试图翻译路径,并抛出空指针异常,因为没有路径。我从来不知道启动时会加载过滤器,但这看起来就像发生了什么。

<!-- SERVLETS -->

<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/index.html</url-pattern>
</servlet-mapping>

<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<!-- FILTERS -->

<filter>
    <filter-name>URLRewriteFilter</filter-name>
    <filter-class>com.ecomm.filters.URLRewriteFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>URLRewriteFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

编辑:

Aug 17, 2010 11:28:12 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet jsp threw exception
java.lang.NullPointerException
    at com.ecomm.helpers.TranslateURLHelper.executeController(TranslateURLHelper.java:47)
    at com.ecomm.filters.URLRewriteFilter.doFilter(URLRewriteFilter.java:41)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:172)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:879)
    at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
    at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
    at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
    at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
    at java.lang.Thread.run(Unknown Source)

【问题讨论】:

【参考方案1】:

看起来您正在使用 Eclipse 在 ROOT 上下文中部署 webapp。 Eclipse 的 Tomcat 插件确实在启动时通过在 ROOT 上触发 GET 请求进行自检。

只需忽略它或修复代码,使其不会引发 NPE。这绝对是 IMO com.ecomm.filters.URLRewriteFilter 中的一个错误。空路径不应算作例外情况。最终用户也可以解雇他们。

【讨论】:

我确实通过 Eclipse 将应用程序作为 ROOT 运行。如果你不介意我问另一个问题,你从哪里读到 Tomcat 在启动时在 ROOT 处触发 GET 请求?谢谢! 这实际上是 Eclipse Tomcat 插件。我以前观察过这种行为,我可以确认您看到的行为。【参考方案2】:

这没有多大意义。过滤器仅适用于请求。您确定您的 Spring 配置中没有任何内容会导致 1) 过滤器类被调用或 2) 触发 http 请求吗?

过滤器中 NPE 的堆栈跟踪显示什么?

我想你会想弄清楚这些请求来自哪里,以便了解如何解决问题。

【讨论】:

我添加了堆栈跟踪。看起来 Tomcat 正在调用 doFilter(),但除了初始化之外,我找不到任何地方表明启动时过滤器加载。我的代码不在 init() 中。我当然可以为 doFilter() 中的所有内容添加一个条件,但我想在这样做之前先确保没有配置选项。【参考方案3】:

我从来不知道启动时会加载过滤器...

我想这取决于您如何定义“加载”。在对请求采取行动之前,将构造一个实例并调用其init(FilterConfig) 方法,因此它的代码有几个机会“在启动时”执行。根据要求,请发布实际异常...

【讨论】:

以上是关于如何让 servlet 过滤器在 Tomcat 中的应用程序启动时停止加载?的主要内容,如果未能解决你的问题,请参考以下文章

在 servlet 重定向之前使用过滤器修改响应 URL (Java/Tomcat)

web.xml - Java Servlet 过滤器 - 在处理 JSP 页面之前未运行(在 Tomcat 上)

如何在 Jetty 中的 /* 上映射 servlet 过滤器?

是否可以在 tomcat servlet 中禁用 jsessionid?

tomcat之过滤器

带有变量的 Servlet 映射(Tomcat 7.0)