java - 未为 Atmosphere servlet 调用 Tomcat 过滤器

标签 java tomcat servlets servlet-filters atmosphere

我使用 Atmosphere 1.0.15 来处理 Tomcat 下的推送通知,几年来它一直运行良好。最近我在我的 Tomcat 中添加了一个简单的过滤器作为测试,它(当前)只记录传入的 URL 并继续。问题是,对于我的 Atmosphere 处理的任何 servlet 路径,Tomcat 似乎根本不会调用过滤器,但对于任何其他 servlet 路径,过滤器都可以正常调用。

这是我的 web.xml 的相关部分:

<servlet>
    <description>AtmosphereServlet</description>
    <servlet-name>AtmosphereServlet</servlet-name>
    <servlet-class>org.atmosphere.cpr.AtmosphereServlet</servlet-class>
    <init-param>
        <param-name>org.atmosphere.atmosphereDotXml</param-name>
        <param-value>WEB-INF/config/atmosphere.xml</param-value>
    </init-param>
    <!-- Reduce memory usage by sharing ExecutorServices -->
    <init-param>
        <param-name>org.atmosphere.cpr.broadcaster.shareableThreadPool</param-name>
        <param-value>true</param-value>
    </init-param>
    <!-- Automatically free Broadcaster objects when the last client on the Broadcaster's channel disconnects -->
    <init-param>
        <param-name>org.atmosphere.cpr.broadcasterLifeCyclePolicy</param-name>
        <param-value>EMPTY_DESTROY</param-value>
    </init-param>
    <load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>AtmosphereServlet</servlet-name>
    <url-pattern>/atmosphere/*</url-pattern>
</servlet-mapping>

<filter>
    <filter-name>MyFilter</filter-name>
    <filter-class>
        com.foobar.MyFilter
    </filter-class>
</filter>
<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

这是我的 atmosphere.xml:

<atmosphere-handlers>
    <atmosphere-handler context-root="/atmosphere/client-notification"
                        class-name="com.foobar.MyClientNotificationAtmosphereHandler"
                        comet-support="org.atmosphere.container.Tomcat7CometSupport">
    </atmosphere-handler>
</atmosphere-handlers>

奇怪的是:如果我点击/atmosphere 下的任何 URL except,我的过滤器就会被调用。例如,这工作正常并且调用了我的过滤器:

https://myserver:444/foo/bar

...但是,对于此 URL(或/atmosphere 下的任何其他 URL),我的过滤器不会针对以下任何一项调用:

https://myserver:444/atmosphere/client-notification
https://myserver:444/atmosphere 
https://myserver:444/atmosphere/foobar

我的第一个想法是 url-pattern 已关闭,但它被设置为“/*”,并且我的过滤器被调用用于除/atmosphere 下的任何其他 URL。我还尝试明确设置 url-pattern:

<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>/atmosphere/client-notification</url-pattern>
</filter-mapping>

...但仍然没有骰子。我错过了什么吗? Atmosphere 是否有可能阻止过滤器在其上运行?据我了解,过滤器总是在 servlet 之前被调用,因此过滤器可以“包装”对它的调用。

非常感谢任何建议!

最佳答案

因此,经过大量的挖掘,我发现了问题所在:由于 AtmosphereServlet 类执行异步 I/O,它实现了 org.apache.catalina.comet.CometProcessor 接口(interface),因此 Tomcat 不会调用正常的过滤器链因为它是一个异步 servlet。相反,我的过滤器必须实现 CometFilter接口(interface),它可以在长时间运行的请求保持 Activity 状态时处理每个 Comet 事件。

一旦我发现 CometProcessor 是罪魁祸首,我就在这里找到了一个类似的 SO 帖子:How do I get the requests for a servlet implementing CometProcessor interface to pass through a filter

关于java - 未为 Atmosphere servlet 调用 Tomcat 过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30721705/

相关文章:

java - 如何检查从 Hibernate 中的查询对象返回的用户列表的类型?

java - 将您的密码隐藏在测试用例的 Java 类文件中

java - 将嵌套对象从 fxml 映射到对象

Tomcat.8.5.15 不接受 URI 中的 "\"并抛出 IllegalArgumentException

java - 一个曾经可以工作的 servlet,现在神奇地不能工作了

java - 仅输入一个字符时 KeyAdapter 发生多个按键事件

Java Web 服务在本地机器上保持编码,在开发时转换

hibernate - 生命周期异常 : Failed to start component deploying war in Tomcat

java - tomcat 错误 "too many open files"

java - servlet 映射 url 模式上的双通配符 (*) 是什么意思?