我使用 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,我的过滤器就会被调用。例如,这工作正常并且调用了我的过滤器:
...但是,对于此 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/