不为Atmosphere servlet调用Tomcat过滤器

时间:2015-06-09 01:39:46

标签: 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>

这是奇怪的事情:如果我在<氛围下点击以外的任何网址,我的过滤器就会被调用。例如,这工作正常,我的过滤器被调用:

  

https://myserver:444/foo/bar

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

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之前调用过滤器,因此过滤器可以“包装”对它的调用。

非常感谢任何建议!

1 个答案:

答案 0 :(得分:0)

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

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