今天写了个脚本,脚本作用是自动打开浏览器显示多个页面并输入测试账号/密码/验证码验证端口服务是否正常(其实可以通过)。
遇到的问题:当所有页面打开后,自由最后一个页面可以正常访问,之前打开的界面都无法访问
代码整理后贴出
排查经过:
一开始一位是脚本切换页面导致一些数据以实发生这种现象,随后是手动打开Chorme浏览器打开两个页面也会出现此问题
之后发现在不同的电脑的不同浏览器不会此问题。去后台filter找到相应代码发现了这段代码
HttpServletRequest req = (HttpServletRequest) request;
if( req.getSession()!=null){
Object sn = req.getSession().getAttribute(Constant.SESSION_USERID);
if (sn == null || "".equals(sn)) {
res.setHeader("sessionStatus", "timeout");
}else if(!AclManageUtil.isLogined(context,req, sn)&&!"true".equals(req.getSession().getAttribute(Constant.SESSION_ISADMIN))){
res.setHeader("sessionStatus", "repeatLogin");
}else{
if(req.getSession().getAttribute(Constant.SESSION_HOS_CODE)==null||"".equals(req.getSession().getAttribute(Constant.SESSION_HOS_CODE))){
res.setHeader("sessionStatus", "notHospital");
}
}
}
由此可知进入了if (sn == null || "".equals(sn))这个判断,说明取出的session无任何信息。
查询资料发现问题是浏览器保存的cookie不分端口,那么访问同一IP的不同端口得到的cookie,后者会把前者覆盖掉。即覆盖cookie的JSESSIONID
浏览器拿着后者JSESSIONID去访问之前端口的服务器,那么之前端口的服务在本地的session池内肯定找不到该对象,就会创建新对象并返回,这样取值为空。
解决方案:
1.在登陆的时候记录所有页面Cookie并保存
2.当手动切换页面是,会导致句柄切换。在句柄切换出发的事件中读取出所对应页面的cookie
3.程序设置浏览器的cookie为上步查出来的cookie
(此方案没有代码实现,目前没必要,我打开界面那是为了查看样式是否正确)
优化方案:
此代码打开网页消耗过多资源,还经历了两次图像截取写入操作
如果仅仅为了测试服务能否访问,数据库是否连通,完全可以用request模拟去实现(图片就访问登录界面对应标签的src属性既可)
该方法内部会进行判断,该客户端是否已经存在session
如果该客户端在此服务器不存在session,就创建一个新的session对象
如果该客户端在此服务器已经存在session,获得已经存在的session返回
那么他是怎么判断的呢,session是基于cookie的,根据抓包可以知道,访问的时候都会有一个名称为JSESSIONID的一个Cookie,这个是session对象的一个编号id。默认是会话级别的(就是浏览器关闭就销毁)也可以通过手动设置持久化。
模拟一个场景,就是客户端第一次访问服务器端就会进行判断这个该服务器端有没有这个客户端的session对象(就是根据你有没有携带JSESSIONID的Cookie来) 根据JSESSIONID去服务器中找有没有对应的session对象,没有就创建,有就直接找到返回,然后响应给客户端,就会把这个JSESSIONID的Cookie发送给客户端,然后每次客户端都会根据这个自己携带的Cookie对象中的JSESSIONID来判断自己服务器端有没有该客户端的session对象,并不是直接根据这个session对象有没有存在来判断!!!这些底层都是自动执行的。
链接:https://zhuanlan.zhihu.com/p/49321547
协助链接:
https://www.cnblogs.com/zjdxr-up/p/11498333.html
https://www.jianshu.com/p/eb3df224045c?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation