目录
除了使用Cookie,Web应用程序中还经常使用Session来记录客户端状态。 Session是服务器端使用的一种记录客户端状态的机制,使用上比Cookie简单一些,相应的也 增加了服务器的存储压力。
1.什么是session
session对象是JSP内置对象,是javax.servlet.http.HttpSession类的对象,在JSP中,session被称为会话。
Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。
如果说Cookie机制是通过检查客户身上的“通行证”来确定客户身份的话,那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。Session相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。
-
session是在一个会话内,在所有JSP页面中共享数据的内置对象。WEB容器为每一个session在服务器内存中分配了独立的内存空间,用于为session存储数据。
-
session是私有的,哪个客户端存储的数据就由哪个客户端来读取。
2.session共享数据
会话的核心是共享数据。例如用户1在a.jsp页面中向session中存储了数据,到b.jsp页面中可以读取到在a.jsp页面中存储的数据,实现同一个用户在一个会话中,在不同的JSP页面中共享数据。用户2在c.jsp页面中向session中存储了数据,到d.jsp页面中可以读取到在c.jsp页面中存储的数据,实现同一个用户在一个会话中,在不同的JSP页面中共享数据。用户1向session中存储的数据,用户2是无法读取的,因此也称session是私有的。
那么服务器是如何知道session中存储的数据是哪个用户存储的呢?服务器是通过SessionID知道的。SessionID是Web服务器生成的、永远不重复的、32位长度的字符串,例如“590C2A202A3F7D40C5F81674F67DC87F”
3.session是私有的
当会话创建时,服务器会生成SessionID,然后将生成的SessionID在服务器上当前会话的session存储空间中保存一份,再将SessionID以Cookie的形式响应到客户端浏览器中一份。在这个会话的后续请求中,每次请求,浏览器都会将SessionID提交到服务器,服务器获取到SessionID后,在所有的session存储空间中寻找哪个session存储空间中标注的SessionID与从浏览器中获取的SessionID相等,若相等,当前会话就可以读取session存储空间中的数据,否则不允许读取。
默认情况下,会话存储空间中存储的数据生命周期是30分钟。也就是说从一个会话最后一次响应开始计时,如果超过30分钟没有发出新的请求,那么存储在会话存储空间中的数据会被自动销毁。也就是说会话创建后,超过30分钟再向服务器发出请求,服务器能够读取到浏览器提交的SessionID,但是服务器session存储空间中的SessionId已经销毁了,此时已经找不到相等的SessionID,这种情况下,提示用户“您未登录或登录超时”。
4.session常用的方法
5.Session的生命周期
Session保存在服务器端。为了获得更高的存取速度,服务器一般把Session放在内存里。每个用户都会有一个独立的Session。如果Session内容过于复杂,当大量客户访问服务器时可能会导致内存溢出。因此,Session里的信息应该尽量精简。
Session在用户第一次访问服务器的时候自动创建。需要注意只有访问JSP、Servlet等程序时才会创建Session,只访问HTML、IMAGE等静态资源并不会创建Session。如果尚未生成Session,也可以使用request.getSession(true)强制生成Session。
Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。用户每访问服务器一次,无论是否读写Session,服务器都认为该用户的Session“活跃(active)”了一次。
6.Session的有效期
由于会有越来越多的用户访问服务器,因此Session也会越来越多。为防止内存溢出,服务器会把长时间内没有活跃的Session从内存删除。这个时间就是Session的超时时间。如果超过了超时时间没访问过服务器,Session就自动失效了。
Session的超时时间为maxInactiveInterval属性,可以通过对应的getMaxInactiveInterval()获取,通过setMaxInactiveInterval(longinterval)修改。
Session的超时时间也可以在web.xml中修改。另外,通过调用Session的invalidate()方法可以使Session失效。
7.实例任务:登录与退出
需求:用户在login.jsp页面登录后才允许访问index.jsp文件,用户在logout.jsp文件退出后不允许访问index.jsp文件。
实现思路:用户在login.jsp文件中登录成功后,将用户名保存到session中,然后页面跳转到index.jsp文件。在index.jsp文件中判断session中是否存储了用户名,如果存储了用户名用户可以访问index.jsp,否则跳转到login.jsp文件。用户访问logout.jsp文件时,销毁session对象(会话结束)。
login.jsp
<form method="post" action="dologin">
用户名:<input type="text" name="UserName" value="" /><br />
密 码:<input type="password" name="UserPass" value="" /><br />
<input type="submit" value="登录" />
</form>
dologin
//设置请求编码
request.setCharacterEncoding("utf-8");
//获取用户名和密码
String UserName =request.getParameter("UserName");
String UserPass =request.getParameter("UserPass");
//验证用户名和密码
if("admin".equals(UserName) && "123".equals(UserPass)){
//验证通过,将用户名保存到session对象中
session.setAttribute("USER", UserName);
//页面跳转到index.jsp页面
response.sendRedirect(request.getContextPath() + "/index.jsp");
}else{
//验证失败,页面跳转到login.jsp
response.sendRedirect(request.getContextPath() + "/login.jsp");
}
代码解析
-
session.setAttribute(“USER”, UserName);表示将UserName的值存储到键为"USER"的session中,实现数据共享的功能。
-
在后续的请求中可以读取回保存到session中的数据。
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
//验证用户是否已经登录
if(session.getAttribute("USER")==null){
response.sendRedirect(request.getContextPath() + "/login.jsp");
return;
}
%>
<body>
欢迎访问首页 ,<a href="<%=request.getContextPath()%>/logout.jsp">退出</a>
</body>
代码解析
-
session.getAttribute(“USER”)表示在当前的会话中获取键为USER的对象。如果不存在返回null。本例中若返回null表示用户未登录,如果返回不是null表示用户已经登录。
-
return表示终止当前页面的执行,即return后面的代码停止运行。
logout.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
//销毁存储在session中的共享数据,会话结束
session.invalidate();
%>
<body>
你已经退出系统
</body>
代码解析
-
session.invalidate()表示销毁存储在session中的数据,会话结束。
-
本例中表示用户退出系统。
运行结果
首先在浏览器地址中输入http://localhost:8080/session/index.jsp,页面会跳转至login.jsp页面。这是因为用户未登录时session中没有存储键为USER的对象,而index.jsp页面中判断session中键为USER对象不等于null时才允许访问。
用户成功登录后,在session中保存了当前用户的用户名,因此可以访问index.jsp页面。
用户退出后,销毁了session,会话结束了,因此在用户退出后再次访问index.jsp页面,依然会跳转到login.jsp页面。
如前所述,session的生命周期默认是30分钟,如果要更改session的生命周期可以通过session.setMaxInactiveInterval(int);更改,方法参数单位为秒。也可以通过web.xml配置session的生命周期,单位是分钟,如果设置负数或0,表示不限制session失效时间。session.setMaxInactiveInterval(int)方法设置的生命周期优先级高于web.xml配置。
在web.xml中更改session生命周期
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<session-config>
<!--单位是分钟 -->
<session-timeout>30</session-timeout>
</session-config>
</web-app>
8.session与Cookie的区别
会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。
在程序中,会话跟踪是很重要的事情。理论上,一个用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话,二者不能混淆。例如,用户A在超市购买的任何商品都应该放在A的购物车内,不论是用户A什么时间购买的,这都是属于同一个会话的,不能放入用户B或用户C的购物车内,这不属于同一个会话。
Cookie与session都可以保存用户的状态,它们之间有什么区别,该如何判断使用哪个方式保存用户的状态呢?
1. cookie数据存放在客户的浏览器上,session数据放在服务器上。
2. cookie中只能存储文本类型,session中能存储Object类型
3. cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session。
4. session会在生命周期内保存在服务器上。当访问增多,会比较占用服务器内存,导致服务器性能下降,考虑到减轻服务器性能方面,应当使用cookie。
5. 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
6. session是内置对象,cookie不是。
注意:
session很容易失效,用户体验很差;
虽然cookie不安全,但是可以加密 ;
cookie也分为永久和暂时存在的;
浏览器 有禁止cookie功能 ,但一般用户都不会设置;
cookie一定要设置失效时间,要不然浏览器关闭就消失了;
9.会话跟踪技术都有哪些?
- cookie的方式: Cookie是Web服务器发送给客户端的一小段信息,客户端请求时可以读取该信息发送到服务器端,进而进行用户的识别。对于客户端的每次请求,服务器都会将Cookie发送到客户端,在客户端可以进行保存,以便下次使用。
- session的方式: 在服务器端会创建一个session对象,产生一个sessionID来标识这个session对象,然后将这个sessionID放入到Cookie中发送到客户端,下一次访问时,sessionID会发送到服务器,在服务器端进行识别不同的用户,Session是依赖Cookie的,如果Cookie被禁用,那么session也将失效, session默认的会话时长为30分钟。
- URL重写技术:就是在URL结尾添加一个附加数据以标识该会话,把会话ID通过URL的信息传递过去,以便在服务端进行识别不同的用户;
- 隐藏表单域:将会话ID添加到HTML[表单]元素中提交到服务器,此表单不再客户端显示。