我使用了支持websocket的spring 4.0.3,我的websocket spring配置为:
<websocket:message-broker application-destination-prefix="/kiford">
<websocket:stomp-endpoint path="/websocket">
<websocket:sockjs/>
</websocket:stomp-endpoint>
<websocket:simple-broker prefix="/queue, /topic"/>
</websocket:message-broker>
当我的客户端连接到服务器时:
this.socket = new SockJS('websocket/');
this.client = Stomp.over(this.socket);
this.client.connect({}, success_callback, error_callback);
弹簧控制台打印了以下错误消息:
2014-05-27 18:22:46.410 [http-apr-8080-exec-5] DEBUG c.k.b.c.SystemExceptionResolver[41] - #系统请求[/kiford-server-1.3/websocket/996/6fodvwrl/eventsource]异常,开始处理异常:
org.springframework.web.socket.sockjs.SockJsException: Uncaught failure in SockJS request, uri=http://localhost:8080/kiford-server-1.3/websocket/996/6fodvwrl/eventsource; nested exception is org.springframework.web.socket.sockjs.SockJsException: Uncaught failure for request http://localhost:8080/kiford-server-1.3/websocket/996/6fodvwrl/eventsource; nested exception is java.lang.IllegalArgumentException: Async support must be enabled on a servlet and for all filters involved in async request processing. This is done in Java code using the Servlet API or by adding "<async-supported>true</async-supported>" to servlet and filter declarations in web.xml. Also you must use a Servlet 3.0+ container
at org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler.handleRequest(SockJsHttpRequestHandler.java:91) ~[SockJsHttpRequestHandler.class:4.0.3.RELEASE]
at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:51) ~[HttpRequestHandlerAdapter.class:4.0.3.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938) [DispatcherServlet.class:4.0.3.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870) [DispatcherServlet.class:4.0.3.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961) [FrameworkServlet.class:4.0.3.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852) [FrameworkServlet.class:4.0.3.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:618) [servlet-api.jar:na]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837) [FrameworkServlet.class:4.0.3.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:725) [servlet-api.jar:na]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:301) [catalina.jar:8.0.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [catalina.jar:8.0.5]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-websocket.jar:8.0.5]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [catalina.jar:8.0.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [catalina.jar:8.0.5]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) [CharacterEncodingFilter.class:4.0.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108) [OncePerRequestFilter.class:4.0.3.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [catalina.jar:8.0.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [catalina.jar:8.0.5]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) [FilterChainProxy$VirtualFilterChain.class:3.2.3.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118) [FilterSecurityInterceptor.class:3.2.3.RELEASE]
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84) [FilterSecurityInterceptor.class:3.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [FilterChainProxy$VirtualFilterChain.class:3.2.3.RELEASE]
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) [ExceptionTranslationFilter.class:3.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [FilterChainProxy$VirtualFilterChain.class:3.2.3.RELEASE]
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103) [SessionManagementFilter.class:3.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [FilterChainProxy$VirtualFilterChain.class:3.2.3.RELEASE]
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113) [AnonymousAuthenticationFilter.class:3.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [FilterChainProxy$VirtualFilterChain.class:3.2.3.RELEASE]
at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:146) [RememberMeAuthenticationFilter.class:3.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [FilterChainProxy$VirtualFilterChain.class:3.2.3.RELEASE]
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154) [SecurityContextHolderAwareRequestFilter.class:3.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [FilterChainProxy$VirtualFilterChain.class:3.2.3.RELEASE]
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45) [RequestCacheAwareFilter.class:3.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [FilterChainProxy$VirtualFilterChain.class:3.2.3.RELEASE]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199) [AbstractAuthenticationProcessingFilter.class:3.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [FilterChainProxy$VirtualFilterChain.class:3.2.3.RELEASE]
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50) [WebAsyncManagerIntegrationFilter.class:3.2.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108) [OncePerRequestFilter.class:4.0.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [FilterChainProxy$VirtualFilterChain.class:3.2.3.RELEASE]
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) [SecurityContextPersistenceFilter.class:3.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [FilterChainProxy$VirtualFilterChain.class:3.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) [FilterChainProxy.class:3.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) [FilterChainProxy.class:3.2.3.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344) [DelegatingFilterProxy.class:4.0.3.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261) [DelegatingFilterProxy.class:4.0.3.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [catalina.jar:8.0.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [catalina.jar:8.0.5]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219) [catalina.jar:8.0.5]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) [catalina.jar:8.0.5]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503) [catalina.jar:8.0.5]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:136) [catalina.jar:8.0.5]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:74) [catalina.jar:8.0.5]
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610) [catalina.jar:8.0.5]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [catalina.jar:8.0.5]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:526) [catalina.jar:8.0.5]
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1017) [tomcat-coyote.jar:8.0.5]
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:652) [tomcat-coyote.jar:8.0.5]
at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:277) [tomcat-coyote.jar:8.0.5]
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2451) [tomcat-coyote.jar:8.0.5]
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2440) [tomcat-coyote.jar:8.0.5]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_55]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_55]
at java.lang.Thread.run(Thread.java:745) [na:1.7.0_55]
Caused by: org.springframework.web.socket.sockjs.SockJsException: Uncaught failure for request http://localhost:8080/kiford-server-1.3/websocket/996/6fodvwrl/eventsource; nested exception is java.lang.IllegalArgumentException: Async support must be enabled on a servlet and for all filters involved in async request processing. This is done in Java code using the Servlet API or by adding "<async-supported>true</async-supported>" to servlet and filter declarations in web.xml. Also you must use a Servlet 3.0+ container
at org.springframework.web.socket.sockjs.transport.TransportHandlingSockJsService.handleTransportRequest(TransportHandlingSockJsService.java:261) ~[TransportHandlingSockJsService.class:4.0.3.RELEASE]
at org.springframework.web.socket.sockjs.support.AbstractSockJsService.handleRequest(AbstractSockJsService.java:317) ~[AbstractSockJsService.class:4.0.3.RELEASE]
at org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler.handleRequest(SockJsHttpRequestHandler.java:88) ~[SockJsHttpRequestHandler.class:4.0.3.RELEASE]
... 62 common frames omitted
Caused by: java.lang.IllegalArgumentException: Async support must be enabled on a servlet and for all filters involved in async request processing. This is done in Java code using the Servlet API or by adding "<async-supported>true</async-supported>" to servlet and filter declarations in web.xml. Also you must use a Servlet 3.0+ container
at org.springframework.util.Assert.isTrue(Assert.java:65) ~[Assert.class:4.0.3.RELEASE]
at org.springframework.http.server.ServletServerHttpAsyncRequestControl.<init>(ServletServerHttpAsyncRequestControl.java:59) ~[ServletServerHttpAsyncRequestControl.class:4.0.3.RELEASE]
at org.springframework.http.server.ServletServerHttpRequest.getAsyncRequestControl(ServletServerHttpRequest.java:202) ~[ServletServerHttpRequest.class:4.0.3.RELEASE]
at org.springframework.web.socket.sockjs.transport.session.AbstractHttpSockJsSession.initRequest(AbstractHttpSockJsSession.java:238) ~[AbstractHttpSockJsSession.class:4.0.3.RELEASE]
at org.springframework.web.socket.sockjs.transport.session.AbstractHttpSockJsSession.handleInitialRequest(AbstractHttpSockJsSession.java:203) ~[AbstractHttpSockJsSession.class:4.0.3.RELEASE]
at org.springframework.web.socket.sockjs.transport.session.StreamingSockJsSession.handleInitialRequest(StreamingSockJsSession.java:54) ~[StreamingSockJsSession.class:4.0.3.RELEASE]
at org.springframework.web.socket.sockjs.transport.handler.AbstractHttpSendingTransportHandler.handleRequestInternal(AbstractHttpSendingTransportHandler.java:66) ~[AbstractHttpSendingTransportHandler.class:4.0.3.RELEASE]
at org.springframework.web.socket.sockjs.transport.handler.AbstractHttpSendingTransportHandler.handleRequest(AbstractHttpSendingTransportHandler.java:58) ~[AbstractHttpSendingTransportHandler.class:4.0.3.RELEASE]
at org.springframework.web.socket.sockjs.transport.TransportHandlingSockJsService.handleTransportRequest(TransportHandlingSockJsService.java:254) ~[TransportHandlingSockJsService.class:4.0.3.RELEASE]
... 64 common frames omitted
似乎应该在servlet配置中添加"异步支持",但即使我也添加了以下内容:
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/spring-config.xml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
<async-supported>true</async-supported>
</servlet>
错误没有消失。怎么了?
我想明白了,
<async-supported>true</async-supported>
也应该添加到过滤器中。
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<async-supported>true</async-supported>
</filter>
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
<async-supported>true</async-supported>
</filter>
在过滤器中也添加<async-supported>true</async-supported>
。