没有为Atmosphere servlet调用Tomcat过滤器



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

这是my 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>
这里有一件奇怪的事情:如果我点击任何URL ,除了中的一个在/atmosphere下,我的过滤器被调用。例如,这工作得很好,我的过滤器被调用:

https://myserver: 444/foo/bar

…但是,对于此URL(或/atmosphere下的任何其他URL),我的过滤器不会为以下任何内容调用:

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

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

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

…但仍然没有成功。我错过什么了吗?大气层是否有可能阻止过滤器在其上运行?据我所知,过滤器总是在servlet之前调用,因此过滤器可以"包装"对它的调用。

任何建议都非常感谢!

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

一旦我发现CometProcessor是罪魁祸首,我在这里找到了一个类似的SO帖子:我如何让实现CometProcessor接口的servlet请求通过过滤器

最新更新