Spring Websocket 404 问题

最近玩Spring Websocket 是碰到404问题,烦死了。下面是服务端配置

web.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd"
	id="WebApp_ID" version="3.1">
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
		<!-- 	data-source-production.xml, -->
			classpath:data-source.xml,
			classpath:spring-action-servlet.xml,
		<!-- 	hr-config.xml, -->
			
			classpath:spring-quartz.xml,
			 
			<!-- classpath:config.xml, -->
			classpath:app-context.xml, 
			classpath:config/dao-context.xml 
		</param-value>
	</context-param>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<listener>
		<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
	</listener>
	<listener>
		<listener-class>com.lh.hrss.sdyw.web.AppContextListener</listener-class>
	</listener>

	<filter>
		<filter-name>characterEncodingFilter</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>
	</filter>
	<filter-mapping>
		<filter-name>characterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<servlet>
		<servlet-name>spring-action</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
	        <param-name>contextConfigLocation</param-name>
	        <param-value>/WEB-INF/classes/spring-action-servlet.xml</param-value>
    	</init-param>
		<load-on-startup>1</load-on-startup>
		
	</servlet>
	<servlet-mapping>
		<servlet-name>spring-action</servlet-name>
		<url-pattern>*.do</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>spring-action</servlet-name>
		<url-pattern>*.html</url-pattern>
	</servlet-mapping>
	
	 
	<!--Axis2 config start-->
	<!-- <servlet>
	<servlet-name>AxisServlet</servlet-name>
	<servlet-class>org.apache.axis2.transport.http.AxisServlet</servlet-class>
	<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>  
 	<servlet-name>AxisServlet</servlet-name>  
 	<url-pattern>/services/*</url-pattern>  
	</servlet-mapping> -->
	
	<session-config>
		<session-timeout>30</session-timeout>
	</session-config>
	<welcome-file-list>
		<welcome-file>/index.do</welcome-file>
	</welcome-file-list>
	<error-page>
		<error-code>500</error-code>
		<location>/show500.do</location>
	</error-page>
	<error-page>
		<error-code>404</error-code>
		<location>/show404.do</location>
	</error-page>
</web-app>

spring.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:cache="http://www.springframework.org/schema/cache"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:websocket="http://www.springframework.org/schema/websocket"  
	xsi:schemaLocation="
	http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.2.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
	http://www.springframework.org/schema/cache
	http://www.springframework.org/schema/cache/spring-cache-4.2.xsd
	http://www.springframework.org/schema/websocket 
	http://www.springframework.org/schema/websocket/spring-websocket.xsd">
	
	<context:component-scan base-package="com.lh.hrss.sdyw.web" />

	<context:component-scan base-package="com.lh.sdyw.neusoft.web" />
	<context:component-scan base-package="com.lh.hrss.sdyw.service" />
	<context:component-scan base-package="com.lihuan.sdyw.service" />
	<context:component-scan base-package="ids" />

	<!-- <bean id="springContextUtil" class="com.lh.hrss.sdyw.SpringContextUtil"
		lazy-init="false"></bean> -->
	<bean id="tsUtil" class="com.lh.hrss.sdyw.util.TsUtil"></bean>

	<bean id="velocityConfig"
		class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
		<property name="resourceLoaderPath" value="/WEB-INF/vm" />
		<property name="configLocation">
			<value>WEB-INF/config/velocity_config.properties</value>
		</property>
		<property name="velocityProperties">
			<props>
				<prop key="velocimacro.library">/common/velocity_common.vm</prop>
			</props>
		</property>
	</bean>
 
	<bean id="viewResolver"
		class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
		<property name="suffix">
			<value>.vm</value>
		</property>
		<property name="contentType" value="text/html;charset=UTF-8" />
		<property name="exposeSessionAttributes" value="true" />
		<property name="exposeRequestAttributes" value="false" />
	</bean>

	<bean id="multipartResolver"
		class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<!-- <property name="maxUploadSize" value="5000000" /> -->
	</bean>

	<bean
		class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
		<property name="interceptors">
			<list>
				<bean class="com.lh.hrss.sdyw.web.interceptor.CommonInterceptor"></bean>
				<bean class="com.lh.hrss.sdyw.web.interceptor.UserLoginProtectInterceptor"></bean>
				<bean class="com.lh.hrss.sdyw.web.interceptor.BizLoginProtectInterceptor"></bean>
				<bean class="com.lh.hrss.sdyw.web.interceptor.ApiInterceptor"></bean>
				<!-- <bean class="com.lh.hrss.sdyw.web.interceptor.SaLoginProtectInterceptor"></bean> -->
			</list>
		</property>
		<property name="useDefaultSuffixPattern" value="true" />
	</bean>

	<bean id="exceptionResolver" class="com.lihuan.common.UserExceptionHandler" />

	<!-- 隐式地向 Spring 容器注册 AutowiredAnnotationBeanPostProcessor、 CommonAnnotationBeanPostProcessor、 
		PersistenceAnnotationBeanPostProcessor 以及 equiredAnnotationBeanPostProcessor 
		这 4 个 BeanPostProcessor。 在配置文件中使用 context 命名空间之前, 必须在 <beans> 元素中声明 context 
		命名空间。 -->
	<context:annotation-config />
	<!-- <context:component-scan/> 配置项不但启用了对类包进行扫描 以实施注释驱动 Bean 定义的功能, 同时还启用了注释驱动自动注入的功能 
		(即还隐式地在内部注册了 AutowiredAnnotationBeanPostProcessor 和 CommonAnnotationBeanPostProcessor) -->
	<!-- 缓存注解驱动 -->
	<cache:annotation-driven />
	<!-- <cache:annotation-driven cache-manager="cacheManager" proxy-target-class="false" 
		mode="proxy"/> -->
	<!-- cacheManager工厂类 -->
	<bean id="cacheManagerFactory"
		class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
		<property name="configLocation" value="classpath:ehcache.xml" />
		<property name="shared" value="true" />
	</bean>
	<!-- 声明cacheManager -->
	<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
		<property name="cacheManager" ref="cacheManagerFactory" />
	</bean>

	<bean id="simpleCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
		<property name="cacheManager" ref="cacheManagerFactory" />
		<!-- 使用缓存 关联ehcache.xml中的缓存配置 -->
		<property name="cacheName" value="myCache" />
	</bean>
	
	<!-- 声明websocket -->
	<websocket:handlers allowed-origins="*">
        <websocket:mapping path="/webSocketServer" handler="systemWebSocketHandler"/>
        <websocket:sockjs/>
    </websocket:handlers>
  
    <bean id="systemWebSocketHandler" class="com.lh.hrss.sdyw.web.test.websocket.SystemWebSocketHandler"/>
    <bean id="taskExecutor" class="org.springframework.core.task.SimpleAsyncTaskExecutor"/>
</beans>

其中红色部分为websocket配置。

服务器类SystemWebSocketHandler代码

package com.lh.hrss.sdyw.web.test.websocket;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;

import org.apache.log4j.Logger;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;

/**
 * @author Administrator
 *
 */
public class SystemWebSocketHandler implements WebSocketHandler {

	private Logger log = Logger.getLogger(SystemWebSocketHandler.class);

	private static final ArrayList<WebSocketSession> users = new ArrayList<WebSocketSession>();;

	@Override
	public void afterConnectionEstablished(WebSocketSession session) throws Exception {
		System.out.println("ConnectionEstablished");
		log.debug("ConnectionEstablished");
		users.add(session);

		session.sendMessage(new TextMessage("connect"));
		session.sendMessage(new TextMessage("new_msg"));

	}
 
	@Override
	public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
		System.out.println("handleMessage" + message.toString());
		log.debug("handleMessage" + message.toString());
		// sendMessageToUsers();
		session.sendMessage(new TextMessage(new Date() + ""));
	}

	@Override
	public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
		if (session.isOpen()) {
			session.close();
		}
		users.remove(session);

		log.debug("handleTransportError" + exception.getMessage());
	}

	@Override
	public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
		users.remove(session);
		log.debug("afterConnectionClosed" + closeStatus.getReason());

	}

	@Override
	public boolean supportsPartialMessages() {
		return false;
	}

	/**
	 * 给所有在线用户发送消息
	 * 
	 * @param message
	 */
	public void sendMessageToUsers(TextMessage message) {
		for (WebSocketSession user : users) {
			try {
				if (user.isOpen()) {
					user.sendMessage(message);
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}


我在客户端用socketJS进行访问连接老是出现404错误,socketJS代码我就不贴了,很简单,网上随便搜。

socketJS关键代码(还是贴吧):

function connect() {  
            if (!url) {  
                alert('Select whether to use W3C WebSocket or SockJS');  
                return;  
            }  
              
              
            //ws = new WebSocket('ws://192.168.10.107:8080/mspjapi/webSocketServer');/* (url.indexOf('sockjs') != -1) ?   
                //new SockJS(url, undefined, {protocols_whitelist: transports}) :  */  
                ws = new SockJS('http://localhost:8080/vrobot_portal/webSocketServer');
              //  ws = new WebSocket('ws://localhost:8080/vrobot_portal/webSocketServer');  
                //console.log("http://192.168.10.107:8080/mspjapi/webSocketServer/sockjs");  
                  
            ws.onopen = function () {  
                setConnected(true);  
                log('Info: connection opened.');  
            };  
              
            ws.onmessage = function (event) {  
                log('Received: ' + event.data);  
            };  
              
            ws.onclose = function (event) {  
                setConnected(false);  
                log('Info: connection closed.');  
                log(event);  
            };  
        }  
  
        function disconnect() {  
            if (ws != null) {  
                ws.close();  
                ws = null;  
            }  
            setConnected(false);  
        }  
  
        function echo() {  
            if (ws != null) {  
                var message = document.getElementById('message').value;  
                log('Sent: ' + message);  
                ws.send(message);  
            } else {  
                alert('connection not established, please connect.');  
            }  
        }  
  
        function updateUrl(urlPath) {  
            if (urlPath.indexOf('sockjs') != -1) {  
                url = urlPath;  
                document.getElementById('sockJsTransportSelect').style.visibility = 'visible';  
            }  
            else {  
              if (window.location.protocol == 'http:') {  
                  url = 'ws://' + window.location.host + urlPath;  
              } else {  
                  url = 'wss://' + window.location.host + urlPath;  
              }  
              document.getElementById('sockJsTransportSelect').style.visibility = 'hidden';  
            }  
        }  
  
        function updateTransport(transport) {  
          transports = (transport == 'all') ?  [] : [transport];  
        }  
          
        function log(message) {  
            var console = document.getElementById('console');  
            var p = document.createElement('p');  
            p.style.wordWrap = 'break-word';  
            p.appendChild(document.createTextNode(message));  
            console.appendChild(p);  
            while (console.childNodes.length > 25) {  
                console.removeChild(console.firstChild);  
            }  
            console.scrollTop = console.scrollHeight;  
        }  


解决方案如下:在web.xml添加下列代码

<servlet-mapping>
		<servlet-name>spring-action</servlet-name>
		<url-pattern>/</url-pattern>
</servlet-mapping>
原因就是:spring之前对 url-pattern配置的*.do和*.html才认,才会通过dispatch进行分发,而websocket注册的地址是 webSocketServer,没有后缀的,所以无法识别匹配出现404错误。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值