java WebSocket 获取httpSession
来源:互联网 发布:java中文api下载 编辑:程序博客网 时间:2024/06/06 20:57
获取HttpSession是一个很有必要讨论的问题,因为java后台需要知道当前是哪个用户,用以处理该用户的业务逻辑,或者是对该用户进行授权之类的,但是由于websocket的协议与Http协议是不同的,所以造成了无法直接拿到session。但是问题总是要解决的,不然这个websocket协议所用的场景也就没了。
获取HttpSession的工具类,源码详细分析
我们先来看一下@ServerEndpoint注解的源码
package javax.websocket.server;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import javax.websocket.Decoder;import javax.websocket.Encoder;@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)public @interface ServerEndpoint { /** * URI or URI-template that the annotated class should be mapped to. * @return The URI or URI-template that the annotated class should be mapped * to. */ String value(); String[] subprotocols() default {}; Class<? extends Decoder>[] decoders() default {}; Class<? extends Encoder>[] encoders() default {}; public Class<? extends ServerEndpointConfig.Configurator> configurator() default ServerEndpointConfig.Configurator.class;}
我们看到最后的一个方法,也就是加粗的方法。可以看到,它要求返回一个ServerEndpointConfig.Configurator的子类,我们写一个类去继承它。
import javax.servlet.http.HttpSession;import javax.websocket.HandshakeResponse;import javax.websocket.server.HandshakeRequest;import javax.websocket.server.ServerEndpointConfig;import javax.websocket.server.ServerEndpointConfig.Configurator;public class HttpSessionConfigurator extends Configurator { @Override public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) { //怎么搞? }}
当我们覆盖modifyHandshake方法时,可以看到三个参数,其中后面两个参数让我们感觉有点见过的感觉,我们查看一HandshakeRequest的源码
package javax.websocket.server;import java.net.URI;import java.security.Principal;import java.util.List;import java.util.Map;/** * Represents the HTTP request that asked to be upgraded to WebSocket. */public interface HandshakeRequest { static final String SEC_WEBSOCKET_KEY = "Sec-WebSocket-Key"; static final String SEC_WEBSOCKET_PROTOCOL = "Sec-WebSocket-Protocol"; static final String SEC_WEBSOCKET_VERSION = "Sec-WebSocket-Version"; static final String SEC_WEBSOCKET_EXTENSIONS= "Sec-WebSocket-Extensions"; Map<String,List<String>> getHeaders(); Principal getUserPrincipal(); URI getRequestURI(); boolean isUserInRole(String role); /** * Get the HTTP Session object associated with this request. Object is used * to avoid a direct dependency on the Servlet API. * @return The javax.servlet.http.HttpSession object associated with this * request, if any. */ Object getHttpSession(); Map<String, List<String>> getParameterMap(); String getQueryString();}
我们发现它是一个接口,接口中规范了这样的一个方法
/** * Get the HTTP Session object associated with this request. Object is used * to avoid a direct dependency on the Servlet API. * @return The javax.servlet.http.HttpSession object associated with this * request, if any. */ Object getHttpSession();
上面有相应的注释,说明可以从Servlet API中获取到相应的HttpSession。
当我们发现这个方法的时候,其实已经松了一口气了。
那么我们就可以补全未完成的代码
import javax.servlet.http.HttpSession;import javax.websocket.HandshakeResponse;import javax.websocket.server.HandshakeRequest;import javax.websocket.server.ServerEndpointConfig;import javax.websocket.server.ServerEndpointConfig.Configurator;/** * 从websocket中获取用户session * * */public class HttpSessionConfigurator extends Configurator { @Override public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) { HttpSession httpSession = (HttpSession) request.getHttpSession();
sec.getUserProperties().put(HttpSession.class.getName(), httpSession); }}
其实通过上面的源码分析,你们应该知道了HttpSession的获取。但是下面又多了一行代码
sec.getUserProperties().put(HttpSession.class.getName(), httpSession);
这行代码又是什么意思呢?
我们看一下ServerEnpointConfig的声明
public interface ServerEndpointConfig extends EndpointConfig
我们发现这个接口继承了EndpointConfig的接口,好,我们看一下EndpointConfig的源码:
package javax.websocket;import java.util.List;import java.util.Map;public interface EndpointConfig { List<Class<? extends Encoder>> getEncoders(); List<Class<? extends Decoder>> getDecoders(); Map<String,Object> getUserProperties();}
我们发现了这样的一个方法定义
Map<String,Object> getUserProperties();
可以看到,它是一个map,从方法名也可以理解到,它是用户的一些属性的存储,那既然它提供了get方法,那么也就意味着我们可以拿到这个map,并且对这里面的值进行操作,
所以就有了上面的
sec.getUserProperties().put(HttpSession.class.getName(), httpSession);
那么到此,获取HttpSession的源码分析,就完成了。
设置HttpSession的类
我们之前有说过,由于HTTP协议与websocket协议的不同,导致没法直接从websocket中获取协议,然后在3.1中我们已经写了获取HttpSession的代码,但是如果真的放出去执行,那么会报空指值异常,因为这个HttpSession并没有设置进去。
好,这一步,我们来设置HttpSession。这时候我们需要写一个监听器。
import javax.servlet.ServletRequestEvent;import javax.servlet.ServletRequestListener;import javax.servlet.http.HttpServletRequest;import org.springframework.stereotype.Component;@Componentpublic class RequestListener implements ServletRequestListener { public void requestInitialized(ServletRequestEvent sre) { //将所有request请求都携带上httpSession ((HttpServletRequest) sre.getServletRequest()).getSession(); } public RequestListener() { } public void requestDestroyed(ServletRequestEvent arg0) { }}
然后我们需要把这个类注册为监听器,如果是普通的Spring工程,或者是servlet工程,那么要么在web.xml中配置,要么使用@WebListener注解。
因为本文是以Spring boot工程来演示,所以这里只写Spring boot配置Listener的代码,其它的配置方式,请自行百度。
这是使用@Bean注解的方式
@Autowird
private RequestListener requestListener;
@Bean public ServletListenerRegistrationBean<RequestListener> servletListenerRegistrationBean() { ServletListenerRegistrationBean<RequestListener> servletListenerRegistrationBean = new ServletListenerRegistrationBean<>(); servletListenerRegistrationBean.setListener(requestListener); return servletListenerRegistrationBean; }
或者也可以使用@WebListener注解
然后使用@ServletComponentScan注解,配置在启动方法上面。
在websocket中获取用户的session
然后刚才我们通过源码分析,是知道@ServerEndpoint注解中是有一个参数可以配置我们刚才继承的类。好的,我们现在进行配置。
@ServerEndpoint(value = "/websocket" , configurator = HttpSessionConfigurator.class)
接下来就可以在@OnOpen注解中所修饰的方法中,拿到EndpointConfig对象,并且通过这个对象,拿到之前我们设置进去的map
@OnOpen public void onOpen(Session session,EndpointConfig config){ HttpSession httpSession= (HttpSession) config.getUserProperties().get(HttpSession.class.getName()); User user = (User)httpSession.getAttribute(SessionName.USER); if(user != null){ this.session = session; this.httpSession = httpSession; }else{ //用户未登陆 try { session.close(); } catch (IOException e) { e.printStackTrace(); } } }
这下我们就从java的webscoket中拿到了用户的session。
- java WebSocket 获取httpSession
- spring websocket 获取httpsession
- WebSocket之获取HttpSession
- webSocket获取HttpSession
- webSocket获取httpSession
- WebSocket之获取HttpSession
- Tomcat下WebSocket获取HttpSession
- websocket @ServerEndpoint注解形式开发 @OnOpen 如何获取httpSession
- WebSocket获取httpSession空指针异常的解决办法
- 获取HttpSession缓存大小(Java代码)
- WebSocket将httpsession作为参数
- Java HttpSession
- Java-HttpSession
- axis中获取HttpSession
- 在spring3.2.0+hibernate3.3.2+struts2 2.2.3中使用websocket,运行环境是tomcat8.0.36,获取HttpSession
- webcoket 做聊天 && websocket 访问HttpSession
- Java web----HttpSession
- Java-HttpSession监听
- 前后端分离springmvc和RESTful理解
- RabbitMQ+PHP消息队列系统
- php使用fopen打开文件输出乱码
- java中的WeakReference
- 192.168.1.10/27,后面的27是什么意思,这样写限制的网络是哪些?
- java WebSocket 获取httpSession
- Notepad++的Json格式化插件
- 桥接模式
- 对称加密与非对称加密优缺点详解
- linux批量改文件名
- UVA1629[Cake slicing] 棋盘动态规划
- SQL优化
- SpringBoot应用与原理之开发环境搭建
- EL表达式和JSTL常用学习