作者
:学Java的冬瓜
博客主页
:☀冬瓜的主页🌙
专栏
:【Java Web】
分享
:我想我能走出这黑夜。——阿普亚虹《存雪》
主要内容
:什么是一次请求?什么是一次会话?session的定位 session对象的作用 为什么需要session来保存会话状态?为什么不使用request保存信息?为什么不使用ServletContext保存信息?session会话保存登录状态 session实现原理 session解决登录页面摆设问题
文章目录
一、session概念
@ 什么是一次请求?
- 用户在浏览器上点了一下,然后页面完全展示并停下来,可以认为是一次请求,请求对应的服务器端的Java对象是:
request
。一次请求对应一个request。
@ 什么是一次会话?
- session又叫会话,打开浏览器,然后各种操作浏览后,把浏览器关了,这个过程叫做一次会话。会话在服务器端也有一个对应的Java对象:
session
。一个会话对应一个session,一个会话包含多个请求。
@ session的定位
- session机制属于B/S结构的一部分。session机制实际上是一个规范,不同语言开发WEB项目也会使用session机制。
@ session对象的作用
- 保存会话状态(如果用户登录成功了,登录成功的这个状态可以用session对象保存)
@ 为什么需要session来保存会话状态?
- 因为
Http是一种无状态协议
。无状态协议即请求的时候,B和S是连接的,请求结束后,连接就断了。设置成这样的目的是为了缓解服务器端的压力。因为请求结束后,连接就断了,所以,服务器是不知道浏览器什么时候关闭的。
@ 为什么不使用request保存信息?为什么不使用ServletContext保存信息?
request
是一次请求一个对象,显然,要保存会话,范围太小,一个用户多次请求会有不同的request对象,这样就达不到保存信息的效果。
ServletContext
对象是服务器启动的时候创建,服务器关闭的时候关闭。对于保存会话来说,范围过大,如果使用,那可能会出现,一个用户登录后,其它用户都不需要再登录,直接进入项目,因为ServletContext对象的域是用户共享的。- request请求域(HttpServletRequest),session会话域(HttpSession),application应用域(ServletContext)。范围:
request < session < application
。 - request请求域,session会话域,application应用域都有的方法:
setAttribute(将数据放入域中)
getAttribute(获取域中的数据)
removeAttribute(删除域中的数据)。
二、session会话保存登录状态
1、如果不使用session,那登录有什么问题?
@首先,怎么实现用户登录的功能
- 步骤一:数据库中添加一个用户表:t_user
用户表中存储的是用户的登录信息,最基本的包括用户名和密码;一般数据库中的这个密码会使用密文的方式(MD5加密),而不是明文;向t_user表中插入用户信息。
注意:注册用户其实就是插入用户信息到用户表中。
- 步骤二:实现一个登陆页面。
登陆页面上有用户名和密码的输入框,用户点击登录,提交表单,提交用户名和密码,提交表单使用"post"方式。 - 步骤三:后台要有一个对应的Servlet处理登录业务
登录成功:跳转到部门列表页面,
登陆失败:跳转到登陆失败页面。 - 步骤四:再增加一个登录失败的页面。
登录页面:
列表页面:
@问题:不经过登录页面也能访问列表页面
- 举个例子:在上面两幅图中,第一个是登陆页面,第二个是列表页面,本来应该必须先登录才能跳转到第二个页面,但是现在,我在地址栏上直接输入第二个页面的地址
http://localhost:8080/oalogin/dept/list
依然能够进行CRUD操作,这代表着,登录就是一个摆设,不需要先登录就可以进行CRUD,非常危险。 - 那么怎么解决?可以使用session会话机制,当用户访问项目时,如果当前用户已经登录过,就放行到列表页面,如果还没登录,就跳转到登录页面。
2、session实现原理
重点:
@ cookie禁用了还能找到session吗?
- cookie:sessionID是以cookie的形式保存在浏览器的缓存中的。
- cookie禁用:
服务器正常发送cookie给浏览器
(即创建好session后把sessionid响应给浏览器时),浏览器拒收了。并不是服务器不发了。这样会导致,浏览器的每一次请求都是一个新的session对象
。 - 那么cookie禁用了,还能找到session吗?
使用URL重写机制:http://localhost:8080/oa/session;jsession=19D1c99560DCDF84839FA43D5
,这种方式开发人员(WEB端)要在每一个路径后加上sessionID,开发成本高。所以大部分浏览器拒绝访问就是,如果禁用cookie,那就不能用了。
3、session解决登录页面摆设问题
原理:同一个用户发送多次请求时:
- 第一次请求时,需要登录,用户提交登录信息,服务器端创建session对象,然后保存登录信息,然后把cookie(包含sessionID)响应给浏览器,浏览器把cookie存在缓存中。
- 以后浏览器发送请求时,服务器会根据浏览器发送的sessionid找会话中有没有该用户登录信息,有则跳转到CRUD页面,会话中没有该用户信息就跳转到登录页面再进行第一步操作。
补充:
- 在访问jsp时,会创建内置的session对象,防止自动产生session内置对象的方法,在jsp中加以下标签:
<%@ page session="false"%>
情况1:如果没有登录,也没有加上面标签,那此时session是jsp的内置对象,不空,但是session域中的内容为空。
情况2:如果已经登录,也不加标签,那会有两个session,一个是内置对象,一个是在服务器端创建的session,session域的内容为用户登录信息。
情况3:如果已经登录,加上标签,那么只有一个session,就是服务器端创建的session,session域的内容为用户登录信息。 - 判断是否已经登陆的条件:
session!=null && session.getAttribute("username")!=null
,这个条件下,jsp中加不加禁止自动产生session的标签都一样,因为如果没有登录,session域中不会有用户信息,就无法通过第二个判断条件。 - 网银安全退出操作,手动销毁session对象:
HttpSession session = request.getSession();
if(session != null){
session.invalidate();
}