基于SpringMVC做Websocket开发过程遇到一系列问题:
问题1:统计了一下大家遇到第一个问题就是连接websocket时候报404错误
先检查连接websocket的url格式:ws://localhost:8080/test/webSocketServer.do,这个.do后缀要匹配SpringMVC拦截后缀
其次检查下Spring配置文件是否有加这个tag:<mvc:annotation-driven/>(加这个会出现中文乱码,下面会讲到),使用Spring websocket需要这个tag支持
当Spring配置文件有使用<context:component-scan/>扫描包,这个tag<context:annotation-config/>可以不去掉。
问题2:连接websocket时候报200,说明已经进入拦截器握手成功,但是没连接上websocket
首先,这个主要原因是在自己的代码上,如果websocket有配置自己定义的拦截器,先检查下拦截器beforeHandshake这个方法,这个方法有个参数Map<String, Object> attributes,不能给这个map的value设成null,否则进不到自己Handler下的这个方法afterConnectionEstablished,就会报200其次,在自定义websocket的Handler和拦截器,加上@Component注解(这个是可选部分,根据自己环境来做选择,基本上可以拔除这个原因,仅做参考)当用户发送请求后,@Requestbody 注解会读取请求body中的数据,默认的请求转换器HttpMessageConverter通过获取请求头Header中的Content-Type来 确认请求头的数据格式,从而来为请求数据适配合适的转换器。例如contentType:applicatin/json,那么转换器会适配 MappingJacksonHttpMessageConverter。响应时候的时候同理,@Responsebody注解会启用 HttpMessageConverter,通过检测Header中Accept属性来适配的响应的转换器。
当在使用SpringMVC做服务器数据接收时,尤其是在做Ajax请求的时候,尤其要注意contentType属性,和accepte 属性的设置,在springmvc-config.xml中配置好相应的转换器。
添加相应转换器:
<bean id="stringHttpMessageConverter"
class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
</list>
</property>
</bean>
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="stringHttpMessageConverter" />新增的
<ref bean="byteArrayHttpMessageConverter" />
<ref bean="jsonHttpMessageConverter" />
<ref bean="jsonHttpMessageConverter4JS" />
</list>
</property>
</bean>
class=" org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> //这是根本原因
<property name="messageConverters">
<list>
<ref bean="stringHttpMessageConverter" />
<ref bean="byteArrayHttpMessageConverter" />
<ref bean="jsonHttpMessageConverter" />
<ref bean="jsonHttpMessageConverter4JS" />
</list>
</property>
</bean>
这块具体的配置可以参考我上一篇文章第4点:http://strongant.iteye.com/admin/blogs/2153820
问题6:websocket相关js代码放在html上可以连接到websocket后端,放在jsp上就连接不成功
如果项目有配置yuicompressor-2.4.7.jar,就要注意了这个问题跟项目环境有关,主要是检查项目web.xml配置,项目里面web.xml配置对jsp,css,do做了自动优化(使用yuicompressor-2.4.7.jar),自动优化会把jsp输出优化成无格式,主要用于传输速度变快,但是变成无格式后websocket相关脚本就出现运行不了,最后把这块jsp自动优化去掉
问题7:js上onopen和onmessage会同时触发
当第一次连接到websocket后台,会触发Handler下的afterConnectionEstablished这个方法发送消息,如果在这个方法有发送消息给自己,在UI上会同时触发onopen和onmessage方法,这个不知道为什么会触发onmessage方法,从websocket上协议讲,只会触发onopen方法!!!
问题8:返回jsp时候,路径出现重复名字导致找不到jsp页面(这个大家估计不会遇到,跟项目配置有关)
比如:正常要返回路径localhost:8080/test/template/js/list.jsp
变成错误路径:localhost:8080/test/template/template/js/list.jsp(多了一个template),后来发现是我的视图解释图配置有点问题
<bean id="viewResolvers"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="cache" value="true" />
<property name="prefix" value="" />
<property name="suffix" value=".jsp" />
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="contentType">
<value>text/html; charset=UTF-8</value>
</property>
</bean>
改成下面这个配置解决这个问题
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/" />
<property name="suffix" value=".jsp" />
</bean>
问题9:启动时候出现这个Factory method 'webSocketHandlerMapping' threw exception; nested exception is java.lang.IllegalStateException: No suitable default RequestUpgradeStrategy found
说明你的容器不支持websocket协议Tomcat7,0.26之后才支持websocket
Jboss as 7不支持websocket,需要要安装插件,可以直接升级到wildfly8支持websocket