亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

springMVC結合websocket小結

2019-11-06 06:02:10
字體:
來源:轉載
供稿:網友

由于瀏覽器的歷史遺留性問題,不是所有的瀏覽器都是支持WebSocket的,尤其是IE10以下,所以才出現了SockJS這樣一個框架,它的原理也很簡單,就是如果你的瀏覽器支持WebSocket那么他就使用webSocket協議通信,入股不支持就使用流傳輸或者輪詢的方式,這樣也保證了資源的最大利用率。

1、websocket相關pom文件配置

<!--websocket--><!-- PRovided Websocket API, because tomcat has its own implementation --><dependency>    <groupId>javax.websocket</groupId>    <artifactId>javax.websocket-api</artifactId>    <version>1.1</version>    <scope>provided</scope></dependency><dependency>    <groupId>org.springframework</groupId>    <artifactId>spring-websocket</artifactId>    <version>4.3.3.RELEASE</version></dependency><dependency>    <groupId>javax.servlet</groupId>    <artifactId>javax.servlet-api</artifactId>    <version>3.1.0</version>    <scope>provided</scope></dependency><!--相關jar--><!-- Json --><dependency>    <groupId>com.fasterxml.jackson.core</groupId>    <artifactId>jackson-core</artifactId>    <version>2.8.1</version></dependency><dependency>    <groupId>com.fasterxml.jackson.core</groupId>    <artifactId>jackson-databind</artifactId>    <version>2.8.1</version>

2、WebSocketConfig----配置WebSocket訪問的地址

package com.bms.web.notice.websocket.config;import com.bms.web.notice.websocket.handler.SystemWebSocketHandler;import com.bms.web.notice.websocket.interceptor.WebsocketHandshakeInterceptor;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;import org.springframework.web.servlet.config.annotation.EnableWebMvc;import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;import org.springframework.web.socket.WebSocketHandler;import org.springframework.web.socket.config.annotation.EnableWebSocket;import org.springframework.web.socket.config.annotation.WebSocketConfigurer;import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;import org.springframework.web.socket.server.HandshakeInterceptor;/** * Created by zhu_kai1 on 2017/2/23. */@Configuration@EnableWebMvc@EnableWebSocketpublic class WebsocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {    // webSocket    private static final String WEBSOCKET_SERVER ="/webSocketServer";    private static final String ECHO ="/echo";    // 不支持webSocket的話用sockjs    private static final String SOCKJS ="/sockjs/webSocketServer";    @Override    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {        //支持websocket 的訪問鏈接        registry.addHandler(systemWebSocketHandler(), WEBSOCKET_SERVER).addInterceptors(handshakeInterceptor());        registry.addHandler(systemWebSocketHandler(), ECHO).addInterceptors(handshakeInterceptor());        //不支持websocket的訪問鏈接        registry.addHandler(systemWebSocketHandler(), SOCKJS).addInterceptors(handshakeInterceptor()).withSockJS();    }    @Bean    public WebSocketHandler systemWebSocketHandler(){        return new SystemWebSocketHandler();    }    @Bean    public HandshakeInterceptor handshakeInterceptor(){        return new WebsocketHandshakeInterceptor();    }    // Allow serving HTML files through the default Servlet    @Override    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {        configurer.enable();    }}

3、HandshakeInterceptor---握手攔截器

package com.bms.web.notice.websocket.interceptor;import com.msk.sso.client.bean.User;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.http.server.ServerHttpRequest;import org.springframework.http.server.ServerHttpResponse;import org.springframework.http.server.ServletServerHttpRequest;import org.springframework.web.socket.WebSocketHandler;import org.springframework.web.socket.server.HandshakeInterceptor;import javax.servlet.http.HttpServletRequest;import java.util.Map;/** * Created by zhu_kai1 on 2017/2/23. */public class WebsocketHandshakeInterceptor implements HandshakeInterceptor{    private static Logger logger = LoggerFactory.getLogger(WebsocketHandshakeInterceptor.class);    public WebsocketHandshakeInterceptor() {    }    // 初次握手訪問前    @Override    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception {        if (request instanceof ServletServerHttpRequest) {            HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest();            //使用userName區分WebSocketHandler,以便定向發送消息            User loginUser= (User) servletRequest.getsession().getAttribute("loginUser");            //存入數據,方便在hander中獲取,這里只是在方便在webSocket中存儲了數據,并不是在正常的httpSession中存儲,想要在平時使用的session中獲得這里的數據,需要使用session 來存儲一下            if(null !=loginUser){                map.put("userName", loginUser.getUserLogin());                logger.info("當前的登陸者為:{}", loginUser.getUserLogin());            }else{                logger.error("沒有獲取session中的當前登陸者信息");            }        }        return true;    }    @Override    public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) {    }}

4、SystemWebSocketHandler----消息處理

package com.bms.web.notice.websocket.handler;import com.bms.web.notice.bean.result.NoticeResult;import com.bms.web.notice.service.CommonService;import com.framework.base.rest.result.BaseRestPaginationResult;import com.framework.core.utils.StringUtils;import com.framework.exception.SystemException;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import org.springframework.web.socket.*;import java.io.IOException;import java.util.ArrayList;import java.util.Collections;import java.util.List;/** * Created by zhu_kai1 on 2017/2/23. */@Componentpublic class SystemWebSocketHandler implements WebSocketHandler {    @Autowired    private  CommonService commonService;    public static final String USERNAME = "userName";    private static Logger logger = LoggerFactory.getLogger(SystemWebSocketHandler.class);    protected final static List<WebSocketSession> sessions = Collections.synchronizedList(new ArrayList<WebSocketSession>());    public SystemWebSocketHandler() {    }    // 連接建立后處理    @Override    public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception {        logger.info("webSocket連接已建立");        sessions.add(webSocketSession);        String userLogin = (String) webSocketSession.getAttributes().get(USERNAME);        BaseRestPaginationResult<NoticeResult> result = null;        if(StringUtils.isNotEmpty(userLogin)){            result = commonService.getNoticeInfo(userLogin);        }        if(null !=result){            sendMessageToAll(new TextMessage(StringUtils.toString(result.getTotal())));        }    }    // 接收客戶端消息,并發送出去    @Override    public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception {        logger.info("發送消息" + webSocketMessage.toString());    }    // 拋出異常時處理    @Override    public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception {        if (webSocketSession.isOpen()) {            webSocketSession.close();        }        sessions.remove(webSocketSession);        logger.info("webSocket異常處理" + throwable.getMessage());        throw new SystemException(throwable);    }    // 連接關閉后處理    @Override    public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {        logger.info("webSocket連接已關閉......" + closeStatus.getReason());        sessions.remove(webSocketSession);    }    @Override    public boolean supportsPartialMessages() {        return false;    }    /**     * 給所有在線用戶發送消息     *     * @param message     */    public void sendMessageToAll(TextMessage message) {        for (WebSocketSession session : sessions) {            try {                if (session.isOpen()) {                    session.sendMessage(message);                }            } catch (IOException e) {                throw new SystemException(e.getMessage());            }        }    }}

5、在對應的spring-mvc.xml配置文件中需要掃描websocketConfig

 <context:component-scan base-package="com.bms.web" use-default-filters="false">        <context:include-filter type="regex" expression="com/.bms/.web/.notice/.websocket/..*"/>    </context:component-scan>

6、jsp需要引用對應的sockjs

<script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script>

7、js調用方法

webSocket: function () {        var host = window.location.host;        var websocket;        var url = null;        if ('WebSocket' in window) {            url = "ws://" + host + Main.contextPath + "/webSocketServer";            websocket = new WebSocket(url);        } else if ('MozWebSocket' in window) {            url = "ws://" + host + Main.contextPath + "/echo";            websocket = new MozWebSocket(url);        } else {            url = Main.contextPath + "/sockjs/webSocketServer";            websocket = new SockJS(url);//建立連接        }        websocket.onopen = function (event) {        };        websocket.onmessage = function (event) {            $("span#noticeTotal").text(event.data);            $("span#notice").text("共" + event.data + "條通知");        };        websocket.onerror = function (event) {        };        websocket.onclose = function (event) {            $.alertMessage.error("與webSocket服務器斷開了連接");        }    }ok,到此大致的websocket已搭建好,但是各位可能會遇到以下問題,請找到對應的錯誤解決,以下解決方法也是從網上查詢到的。

問題1:統計了一下大家遇到第一個問題就是連接websocket時候報404錯誤

先檢查連接websocket的url格式:ws://localhost:8080/web/webSocketServer,這個webSocketServer要匹配websocketConfig中的

registry.addHandler(systemWebSocketHandler(), "/webSocketServer").addInterceptors(handshakeInterceptor());

其次檢查下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

問題3:連接websocket時候,如果缺少配置會報415 Unsupported Media Type請求的格式不受請求頁面的支持錯誤

當用戶發送請求后,@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>

問題4:網上例子都有說要在web.xml下的servlet和filter里面加上<async-supported>true</async-supported>

沒有影響websocket是可以連接成功的(小編就是這種方式實現的),可以不用加,這個是用來支持異步的servlet3.x,建議不用加,除非有用到這個特性(小編沒有試,這個可以自行對比下)

問題5:添加<mvc:annotation-driven/>這個出現中文亂碼

剛開始時候,所有瀏覽器都出現中文亂碼,后來解決在Chrome瀏覽不會出現中文亂碼,但是在FF下會出現。原因有三個:第一,MessageConverter轉換器沒配置相應的<property name="supportedMediaTypes">屬性,第二,bean和tag的先后順序不對,第三,當使用<mvc:annotation-driven/>這個tag時候,請求處理器就會變成RequestMappingHandlerAdapter,跟進代碼就會發現不是采用AnnotationMethodHandlerAdapter,所以配置時候要改成:org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter統一解決辦法是:要注意bean和tag的先后順序<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><context:component-scan base-package="掃描Spring controller包路徑" /><context:component-scan base-package="掃描websocket包路徑"/><context:annotation-config />  //這個標注可以不加<mvc:annotation-driven/>//這個tag一定要放在上面代碼最后,這是也是亂碼根源之一

問題6:啟動時候出現這個Factory method 'webSocketHandlerMapping' threw exception; nested exception isjava.lang.IllegalStateException: No suitable default RequestUpgradeStrategy found

 

說明你的容器不支持websocket協議Tomcat7,0.26之后才支持websocket

Jboss as 7不支持websocket,需要要安裝插件,可以直接升級到wildfly8支持websocket

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品无码久久久久久国产| 精品一区精品二区| 欧美成人在线免费| 国产美女久久精品| 欧美精品久久一区二区| 成人黄在线观看| 91香蕉嫩草影院入口| 91精品国产成人www| 国产亚洲精品美女久久久久| 日韩电视剧在线观看免费网站| 欧美另类精品xxxx孕妇| 久久久亚洲影院| 91精品国产91久久久久久| 亚洲激情在线视频| 国产精品影片在线观看| 亚洲欧美日本伦理| www.久久久久| 日韩在线观看电影| 国产一区二区三区视频在线观看| 中日韩美女免费视频网站在线观看| 成人在线视频福利| 国产日本欧美一区二区三区| 日产精品99久久久久久| 国产一区二区三区日韩欧美| 欧美最猛黑人xxxx黑人猛叫黄| 国产精品美女主播在线观看纯欲| 国产69精品久久久久9| 成人h猎奇视频网站| 韩国欧美亚洲国产| 97欧美精品一区二区三区| 欧美日产国产成人免费图片| 尤物精品国产第一福利三区| 日韩av在线免费观看| 国产成+人+综合+亚洲欧洲| 亚洲综合中文字幕68页| 97在线看免费观看视频在线观看| 日本欧美在线视频| 中文字幕亚洲欧美日韩2019| 久久精品国产欧美激情| 国产美女精品免费电影| 成人福利网站在线观看11| 欧美激情在线狂野欧美精品| 91精品久久久久久久久久| 国内精品国产三级国产在线专| 国产a∨精品一区二区三区不卡| 欧美性猛交xxxx| 亚洲全黄一级网站| 91丨九色丨国产在线| 国产精品久久久久久婷婷天堂| 国产精品视频精品视频| 欧美另类暴力丝袜| 高潮白浆女日韩av免费看| 久久久久久亚洲精品中文字幕| 91精品国产综合久久久久久蜜臀| 欧美人与性动交a欧美精品| 91在线网站视频| 中文字幕成人在线| 久久精品一偷一偷国产| 日韩精品福利在线| 欧美国产日韩精品| 国产欧美va欧美va香蕉在线| 亚洲视频在线观看| 国产精品日韩专区| 久久偷看各类女兵18女厕嘘嘘| 国产精品免费网站| 久久久久五月天| 亚洲精品之草原avav久久| 91高清在线免费观看| 欧美亚洲第一页| 国产精品视频精品视频| 97国产精品人人爽人人做| 欧美在线视频在线播放完整版免费观看| 日韩免费电影在线观看| 最新日韩中文字幕| 美日韩精品视频免费看| 性色av一区二区三区| 欧美日韩午夜剧场| 亚洲视频在线观看免费| 国产伊人精品在线| 青青草原一区二区| 国内精品免费午夜毛片| 4438全国亚洲精品在线观看视频| 欧美一性一乱一交一视频| 亚洲黄页网在线观看| 日韩欧美中文字幕在线观看| 久久福利网址导航| 亚洲中国色老太| 在线日韩日本国产亚洲| 国产欧美一区二区三区在线看| 久久久噜噜噜久久久| 成人精品网站在线观看| 精品国产区一区二区三区在线观看| 日韩成人xxxx| 中文字幕亚洲天堂| 亚洲精品在线观看www| 97精品久久久中文字幕免费| 久久久久久中文| 成人国产精品一区| 日本亚洲欧洲色| 超碰97人人做人人爱少妇| 美女999久久久精品视频| 亚洲精品av在线| 久久69精品久久久久久国产越南| 色噜噜国产精品视频一区二区| 日韩一区二区欧美| 日韩av电影国产| 国产精品久久久久久久一区探花| 国产精品香蕉在线观看| 在线观看亚洲视频| 久久久精品网站| 欧美第一淫aaasss性| 亚洲欧美视频在线| 国产日韩av在线| 成人观看高清在线观看免费| 精品久久久久国产| 91精品国产高清久久久久久久久| 久久99青青精品免费观看| 成人看片人aa| 亚洲激情第一页| 搡老女人一区二区三区视频tv| 欧美俄罗斯性视频| 日韩精品免费看| 美女少妇精品视频| 影音先锋欧美精品| 国产精品三级美女白浆呻吟| 亚洲精品美女视频| 国产精品爽爽爽爽爽爽在线观看| 欧美视频在线观看 亚洲欧| 视频一区视频二区国产精品| 亚洲第一av在线| 欧美丰满少妇xxxxx| 国产精品天天狠天天看| 日韩美女av在线免费观看| 亚洲自拍偷拍区| 狠狠躁夜夜躁人人爽超碰91| 国产精品ⅴa在线观看h| 91影院在线免费观看视频| 亚洲人成免费电影| 精品福利樱桃av导航| 亚洲999一在线观看www| 久久99国产精品久久久久久久久| 国产精品久久久久久久久久久久久| 色偷偷av一区二区三区| 日韩中文字幕精品视频| 成人免费网站在线看| 欧美激情一区二区久久久| 亚洲**2019国产| 精品国偷自产在线视频99| 欧美疯狂做受xxxx高潮| 亚洲影院色在线观看免费| 亚洲性视频网站| 亚洲第一精品福利| 中文国产亚洲喷潮| 国产成人精品在线视频| 国产丝袜一区二区三区免费视频| 萌白酱国产一区二区| 国产一区二区久久精品| 欧美精品videos性欧美| 国产精品久久久一区| 日韩精品在线播放| 欧美激情视频一区| 日韩av在线不卡| 超碰91人人草人人干| 国产精品久久一区主播|