会话:
用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应(几个浏览器就几个会话)
会话跟踪(会话功能):
一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据,服务器用来识别浏览器的过程,这个过程就是会话跟踪
为什么会需要会话技术呢:
首先HTTP协议为了保证让每次请求之间相互独立,互不影响,因此是无状态的,如果HTTP协议是有状态的,那每次请求后面都要携带大量数据,当数据很大时访问速度会很慢
所以每次浏览器向服务器请求时,服务器都会将该请求视为新的请求,因此我们无法做到浏览器与服务器的资源共享,这就需要会话技术来实现资源共享了
会话示例:
登录页面的验证码功能:生成验证码和输入验证码点击注册这也是两次请求,这两次请求的数据之间要进行对比,相同则允许注册,不同则拒绝注册,该功能的实现也需要在同一次会话中共享数据
实现方式:
1. 客户端会话技术:Cookie
2. 服务器端会话技术:Session
概念:
Cookie:客户端会话技术,将数据保存到客户端,以后每次请求都携带Cookie数据进行访问
Cookie的工作流程:
Cookie的作用:
注意:
浏览器对于单个cookie 的大小有限制(3kb) 以及对同一个域名下的总cookie数量也有限制(20个)
创建cookie对象:
Cookie cookie = new Cookie("key","value");
在jsp页面中获取cookie数据:
使用EL表达式(其中key需要为具体键名):
${cookie.key.value}
除了创建cookie对象与在jsp中获取数据之外,我们只需要知道服务器端怎么发送cookie对象给浏览器与怎么获取cookie对象:
发送cookie:使用response对象的addCookie即可(所以对于cookie要一个个发):
response.addCookie(cookie);
获取cookie对象:使用request对象的getCookies()方法即可,该方法返回一个cookie对象数组:
Cookie[] getCookies()
获取cookie的数组对象以后我们可以遍历数组,然后通过cookie的getName()与getValue()方法获取对应数据
对于Cookie的实现原理是基于HTTP协议的,其中设计到HTTP协议中的两个请求头信息:
而cookie就是基于响应头set-cookie和请求头cookie实现
当我们从服务器往浏览器中发送cookie对象时,tomcat服务器会自动设置对应的响应头:
set-cookie:key=value
浏览器解析这个响应头之后就会将对应的cookie数据存入到内存中
当浏览器向服务器发送请求时,浏览器会自动将所有cookie数据通过请求头发送给服务器:
cookie:key1=value1;key2=value2;...
是可以一次发送多个cookie的,只需创建多个Cookie对象,使用response调用多次addCookie方法发送cookie即可
默认情况下,当浏览器关闭后,Cookie数据被销毁
持久化存储实现方式:
可以通过cookie的setMaxAge(int seconds)方法来设置cookie在浏览器的存活时间:
1.在Servlet中对中文进行URL编码,采用URLEncoder.encode(),将编码后的值存入Cookie中
2.获取Cookie中的值时,获取的值为URL编码后的值
3.将获取的值在进行URL解码,采用URLDecoder.decode(),就可以获取到对应的中文值
假设在一个tomcat服务器中,部署了多个web项目,那么在这些web项目中cookie能不能共享?
默认情况下cookie不能共享
设置可以共享的方式:通过cookie的setPath方法:
setPath(String url):设置cookie的获取范围。默认情况下,为当前的虚拟目录(也就是项目目录)
如果要共享,则可以将path设置为"/"
不同的tomcat服务器间cookie数据怎么共享
通过Cookie的setDomain方法:
setDomain(String url):如果设置一级域名相同,那么多个服务器之间cookie可以共享
示例:setDomain(".baidu.com"),那么tieba.baidu.com和news.baidu.com中cookie可以共享
概念:
服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中,因为将数据存在浏览器中限制比较多并且也不太安全,因此我们一般存储在服务器端中。JavaEE提供了HttpSession接口,我们通过这个接口就可以实现数据共享
注意:
session用于存储一次会话的多次请求的数据,存在服务器端
session与Cookie的区别:
1. session存储数据在服务器端,Cookie在客户端
2. session没有数据大小限制,Cookie有
3. session数据安全,Cookie相对于不安全
4. session是javaweb的域对象,cookie不是(也就是说一个session可以存储多个键值对信息)
5. 服务器性能:Cookie不占服务器资源,Session占用服务器资源
session与Cookie分别的应用场景:
结论:
获取HttpSession对象可以通过request对象的getSession()方法:
HttpSession session = request.getSession();
常用API:
方法 | 说明 |
---|---|
Object getAttribute(String name) | 获取指定名称的数据 |
void setAttribute(String name, Object value) | 将数据存入session域中 |
void removeAttribute(String name) | 将指定名称对应的键值对数据从域对象中删除 |
显然,都是域对象共有的方法,对于这些方法的使用我们已经很熟悉了
注意:
Session中可以存储的是一个Object类型的数据,也就是说Session中可以存储任意数据类型
当我们在同一个会话中,获取的session对象是唯一的,但是前面有讲过HTTP协议是无状态的,那服务器是怎么保证同一个会话中使用同一个Session呢?
其实当会话建立创建Session对象时,tomcat服务器会给Session设置一个唯一的id,当响应的时候会响应这样子一个响应头:
set-cookie:JSESSIONID=id值
因此当浏览器再次请求时,会将这个cookie数据发送给服务器,服务器一解析,发现这个ID,自动将这个Session对象给这次请求使用,这也就保证了同一个会话中使用同一个Session,这也是为什么我们说Session是基于Cookie实现的
以下情况Session对象被销毁:
<session-config>
<session-timeout>300session-timeout>
session-config>
如果没有进行配置,那销毁时间的默认值30分钟是在tomcat的web.xml配置文件中写死的:
首先,当服务器被正常的关闭与启动之后,session对象还是存在的(避免数据丢失)
而服务器的正常关闭与启动是指使用命令行的方式,进入到pom.xml的目录下,输入启动的指令,例如:tomcat7:run
,而正常关闭是指在启动的命令行界面,输入ctrl+c
那么服务器是怎么实现重启之后session对象还在呢?这就涉及到了Session对象的钝化与活化:
钝化:在服务器正常关闭后,Tomcat会自动将Session数据写入硬盘的文件中(在正常关闭服务器时需要等一会才能关闭,就是因为在做session的序列化操作)
钝化的数据路径为:项目目录\target\tomcat\work\Tomcat\localhost\项目名称\SESSIONS.ser
活化:再次启动服务器后,从文件中加载数据到Session中
数据加载到Session中后,路径中的SESSIONS.ser文件会被删除掉
但是注意,session只能在服务器正常关闭后还在,当浏览器重启之后就是一次新的会话了,此时session还是得不在,因此只有cookie可以永久化保存数据,因为cookie可以保存到硬盘中