session为空服务器会怎么样,关于session获取引发的问题,以及对其进行的思考

最近玩了下使用的websocket技术做消息推送,过程中遇到了session的问题,问题描述如下:

用户登录的时,将用户信息保存到session中,用户主页通过ws协议的方式访问服务器,访问地址:ws://127.0.0.1:8080/webSocketServer",websocket拦截器获取用户seesion的时候,发现session为null。

尝试调试过多次,session获取始终未空,问题出在哪呢?

我们来看一下session的概要:

Session概要

Session 是用于保持状态的基于 Web 服务器的方法,在 Web 服务器上保持用户的状态信息供在任何时间从任何页访问。Session 允许通过将对象存储在 Web 服务器的内存中在整个用户会话过程中保持任何对象。当我们使用用户名和密码登陆网站,系统会首先验证当前登陆用户是否合法,当合法后将用户名等相关信息保存在Session 中。登陆后点击进入某功能页面时,系统也会去判断当前你是否有访问权限,判断的方式是验证Session 中的内容是否正确。

Session是客户端与服务器端建立的会话,总是放在服务器上的,服务器会为每次会话建立一个sessionId,每个客户会跟一个sessionID对应。并不是关闭浏览器就结束了本次会话,通常是用户执行“退出”操作或者会话超时时才会结束。

session代表的是一个回话,在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下)。因此,在需要保存用户数据时,服务器程序可以把用户数据写到用户浏览器独占的session中,当用户使用浏览器访问其它程序时,其它程序可以从用户的session中取出该用户的数据,为用户服务。

服务器是如何实现一个session为一个用户浏览器服务的?

服务器创建session出来后,会把session的id号,以cookie的形式回写给客户机,这样,只要客户机的浏览器不关,再去访问服务器时,都会带着session的id号去,服务器发现客户机浏览器带session id过来了,就会使用内存中与之对应的session为之服务。

来看一下session为null的实际案例:

服务端设置session的代码:

@RequestMapping("")

public String index(HttpServletRequest httpRequest, String nickname) {

HttpSession httpSession = httpRequest.getSession();

System.out.println("###跳转进入到了首页###");

User user = new User();

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

String dateString = formatter.format(new Date());

user.setId(dateString + "-" + nickname);

user.setNickname(nickname);

// 登录操作

// 判断是否是一个已经登录的用户,没有则登录

if (null != httpSession.getAttribute("loginUser")) {

// 清除旧的用户

httpSession.removeAttribute("loginUser");

}

// 将用户放入session

httpSession.setAttribute("loginUser", user);

return "redirect:/index/mainpage";

}

前端sebsocket获取session的代码:

var url = "ws://127.0.0.1:8080/"+ "webSocketServer";

ws = websocket.util.getWs(url);

websocket.util.onopen(ws);

public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,

Mapattributes) throws Exception {

System.out.println("握手之前····");

if (request instanceof ServletServerHttpRequest) {

ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;

HttpSession session = servletRequest.getServletRequest().getSession(false);

//如果用户已经登录,允许聊天

if(session !=null && session.getAttribute("loginUser")!=null){

//获取登录的用户

User loginUser=(User)session.getAttribute("loginUser") ;

//将用户放入socket处理器的会话(WebSocketSession)中

attributes.put("loginUser", loginUser);

System.out.println("Websocket:用户[ID:" + (loginUser.getId() + ",Name:"+loginUser.getNickname()+"]要建立连接"));

}else{

//用户没有登录,拒绝聊天

//握手失败!

System.out.println("--------------握手已失败...");

return false;

}

}

return super.beforeHandshake(request, response, wsHandler, attributes);

}

通过beforeHandShake方法获取session为null,发现使用ip的方式,不是同一个sessionId,得到的session自然为null,改为如下方式进行请求就可以了:

var url = "ws://" + path + "webSocketServer";

ws = websocket.util.getWs(url);

websocket.util.onopen(ws);

目前很多项目采用的是前后台分离的情况,关于前后端分离的session情况,笔人也测试过,目前前后台分离分2种情况部署:

一、在同一个服务器(tomcat)下部署,同源

服务A:服务端代码:

@RequestMapping(value = "test", method = RequestMethod.GET)

@ResponseBody

public String test(HttpServletRequest request, HttpServletResponse httpResponse) {

/*httpResponse.setHeader("Access-Control-Allow-Credentials", "true");

httpResponse.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:8080");

httpResponse.setHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");

*/

//判断,如果没有session,则跳到登录页面

HttpSession session = request.getSession();

if(null != session.getAttribute("loginUser")){

User user = (User) session.getAttribute("loginUser");

System.out.println("session 不为空");

return "session 不为空 nicknage :" + user.getNickname();

}else{

System.out.println("session ---------------------------- null");

return "session ---------------------------- null";

}

}

客户端A:前端代码:

主界面

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值