您好,登錄后才能下訂單哦!
這期內(nèi)容當中小編將會給大家?guī)碛嘘P(guān) spring中怎么利用websocket獲取HttpSession,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
一個普通網(wǎng)站,用戶登錄后,將用戶信息存在HttpSession中?,F(xiàn)在網(wǎng)站需要加入即時聊天功能,打算使用Websocket實現(xiàn),需要在Websocket中拿到HttpSession來表示用戶。
/**
* 交流
* @param chatMessage
*/
@MessageMapping("/chat")
public void chat(HttpSession session, @RequestBody ChatMessage chatMessage) {
User user = (User)session.get("user"); // error
chatService.chat(user,chatMessage);
}
普通的注入HttpSession是不行的,因為Websocket連接建立后,并不會HTTP協(xié)議那樣,每次傳輸數(shù)據(jù)都會帶上sessionid。
解決思路
在Websocket連接建立階段(此時還是HTTP協(xié)議)攔截HTTP請求,獲取到HttpSesion并保存。
實現(xiàn)
本來想自己寫個類,但發(fā)現(xiàn)Spring Websocket已經(jīng)提供了這樣的攔截器HttpSessionHandshakeInterceptor,直接使用即可。
Websocket 代理配置
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/chat");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/endpoint").setAllowedOrigins("*").addInterceptors(new HttpSessionHandshakeInterceptor()).withSockJS();
}
}
這里和普通的Websocket配置差不多,最大的區(qū)別是addInterceptors(new HttpSessionHandshakeInterceptor()),它把HttpSessionHandshakeInterceptor加入到了攔截鏈中。
我們可以看一下HttpSessionHandshakeInterceptor源碼中的相關(guān)方法
// 在握手完成前(連接建立階段)
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
HttpSession session = this.getSession(request);
if (session != null) {
if (this.isCopyHttpSessionId()) {
attributes.put("HTTP.SESSION.ID", session.getId()); // 保存 sessionid
}
Enumeration names = session.getAttributeNames();
while(true) {
String name;
do {
if (!names.hasMoreElements()) {
return true;
}
name = (String)names.nextElement();
} while(!this.isCopyAllAttributes() && !this.getAttributeNames().contains(name));
attributes.put(name, session.getAttribute(name)); // 保存HttpSession中的信息
}
} else {
return true;
}
}
// 獲取HttpSession
private HttpSession getSession(ServerHttpRequest request) {
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest serverRequest = (ServletServerHttpRequest)request;
return serverRequest.getServletRequest().getSession(this.isCreateSession());
} else {
return null;
}
}
通過源碼我們可以知道,HttpSessionHandshakeInterceptor將HttpSession中的值保存到了一個Map里面,通過搜索spring的官方文檔,我發(fā)現(xiàn)可以通過注入SimpMessageHeaderAccessor在Controller方法中獲取到那些值。
/**
* 交流
* @param chatMessage
*/
@MessageMapping("/chat")
public void chat(SimpMessageHeaderAccessor headerAccessor, @RequestBody ChatMessage chatMessage) {
User user = (User) headerAccessor.getSessionAttributes().get("user"); // right
chatService.chat(user,chatMessage);
}
上述就是小編為大家分享的 spring中怎么利用websocket獲取HttpSession了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。