我使用tomcat中的Guice-servlets和websocket创建了一个示例webapp,现在一旦使用guice过滤器就停止工作。
基本信息:
在我的web.xml中,我使用GuiceBasedListener初始化了Guiceservlet
<web-app>
<listener>
<listener-class>test.GuiceBasedListener</listener-class>
</listener>
<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>GuieBasedListener代码,它将所有请求/*绑定到MyDispatcher
public class GuiceBasedListener extends GuiceServletContextListener {
protected Injector getInjector() {
return Guice.createInjector( new ServletModule() {
@Override
protected void configureServlets() {
bind(MyDispatcher.class).asEagerSingleton();
serve("/*").with(MyDispatcher.class);//////IMPORTANT LINE//
}
});}}只使用字符串响应的MyDispatcher代码
public class MyDispatcher extends HttpServlet {
@Inject private Injector injector;
public MyDispatcher() {}
public void service(ServletRequest req, ServletResponse resp) throws IOException, ServletException {
resp.getOutputStream().print("SUCCESS:" + req);
}
}此外,我还有一个用于Websocket的@ServerEndPoint
@ServerEndpoint(value = "/websocket/chat2")
public class WebSocket{
....
@OnOpen
public void start(Session session) {
System.out.println("Staring:"+this);
}
....
}Observations:
SUCCESSserve("/*").with(MyDispatcher.class);,基本上如果我们关闭guice路由,websocket就开始工作了< servlet-mapping > < servlet-name > HelloWorld< / servlet-name > < url-pattern > /* < / url-pattern > < / servlet-mapping >我错过了什么或者做错了什么?
编辑:
Observation-conti:
FILTER响应。public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { response.getOutputStream().print("FILTER"); }
并将我的web.xml改为
<web-app>
<filter>
<filter-name>myFilter</filter-name>
<filter-class>test.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>现在,按预期按http://localhost:8080/app/x返回FILTER。但是,试图连接websocket失败了,因为请求显示了如下所示。我还注意到,在更改字符串MyFilter时,返回响应更改中的内容长度,这意味着请求在tomcat处理websocket之前到达MyFilter。

TOMCAT 8.0,窗口7,Java 1.7,Guice 4.0,Guice-servlet-4.0
发布于 2017-05-31 20:03:06
在我看来,这也是一个Guice问题(正如评论中已经提到的)。在同一个应用程序中使用servlet和WebSockets不应该是一个问题,即使使用涵盖/*的servlet映射也是如此。
有关servlet和过滤器的相关内容:
因此,如果WsFilter是第一个,它将首先拦截请求,然后是检查是否是WebSocket升级请求。
如果它确实是一个WebSocket连接,则过滤器将不会将它传递给链的其余部分。
如果它是另一种类型的请求(GET,POST.),它将传递它,然后Guice将完成它的任务。
(所以你在这里找到了第一个解决方案)
如果Guice过滤器是第一个,并且您使用serve("/*")...,那么它会破坏您的WS。
如果您注释掉了serve("/*")...,那么GuiceFilter是否是第一个并不重要,WsFilter甚至可能不存在:您可以到达您的WS (只确定GuiceFilter是可以的)。
所以Guice在servlet映射之上有自己的“拦截层”,我认为这就是破坏WebSockets的原因。我不知道Guice中是否有bug或任何需要修复的地方(我的意思是可能的,但不知道具体是什么),但是您可以指定Guice的异常(与web.xml中的servlet映射不同)。
代之以:
serve("/*").with(TestServlet.class);在这方面:
serveRegex("/(?!websocket/).*").with(TestServlet.class);
// Regex that accepts /.* but excludes /websocket/.*这样,您可以保留/*上的servlet映射,并在不需要的情况下删除WsFilter。(测试,为我工作)
这是第二种解决方案,它还允许为非WebSocket指定异常。
https://stackoverflow.com/questions/44216801
复制相似问题