我正在使用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下的任何其他网址),我的过滤器不会针对以下任何内容调用:
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之前调用过滤器,因此过滤器可以“包装”对它的调用。
非常感谢任何建议!
答案 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