一、Session (HttpSession的对象):
1.HttpSession的概述:
1)Cookie是由http协议制定的,是由服务器创建,是客户端对象,保存在
浏览器中,跟踪客户端;
1)Cookie是http制定的(只要web开发使用的协议是http就有Cookie)
2)Cookie是服务器去创建保存数据,但是最终是保存在浏览器上的
3)Cookie是客户端对象,用于跟踪客户端;
HttpSession区别于Cookie,它是由JavaWeb提供的而不是Http协议制定的,
session是服务器端对象,保存在服务器端(session缓存中),服务器对象,
是专门用于会话跟踪的对象。
1)Session是javaWeb的技术(只要是javaWeb开发就有Session)
2)Session也是由服务器创建保存数据,但是最终还是保存在服务器中(
保存在服务器的Session缓存(Map<sessionid,Session>))
3)Session是服务器端对象,跟踪’会话‘
2)HttpSession是javaWeb四大域对象之一(其本身是个Map),所以它也有setAttribute(),
getAttribute(),removeAttribute()方法.
session的作用域就在一个‘会话’中,在同一个会话中共享同一个session。
3)HttpSession底层依赖于Cookie或者是URL重写。
2.HttpSession的作用:
1)会话:是一个浏览器对服务器的多次连贯性请求。所谓连贯性请求,就是该浏览器
多次请求服务器中间没有关闭浏览器。
浏览器的开启到关闭就是一个会话,一个会话一个session
2)会话范围:就是某个浏览器从开启首次访问服务器开始,到该浏览器关闭结束对服务器的访问。
3)服务器会自动为每个会话创建一个session对象(即使是同一个用户使用不同的浏览器
登录,也相当于是两个会话,服务器也会创建两个不同的session对象),一个session就好比
一个会话在服务器端的账户,它们被服务器保存到一个Map集合中,这个Map集合被称之为
session缓存。
Session也不能跨浏览器,因为一个浏览器的开启到关闭就是一个新的会话;
3.获取HttpSession对象:
1>Servlet中获取session对象:
HttpSession session = request.getSession();
2>Jsp中获取session对象:session是Jsp的九大内置对象之一,不用创建就可直接使用。
session的核心用法,就是session是一个再同一会话之间被共享的域对象,
那么浏览器开启到关闭,浏览器对服务器的多次请求就是一个会话,那么
就是在这多次请求中可以使用同一个session来传递数据。
4.session的原理:
session的底层依赖于cookie,其实当调用request.getSession()方法时,
服务器会从请求request对象中获取名叫JSESSIONID的cookie,其值就是一个
sessionID:(Cookie:JSESSIONID=asfadas3313213)
1>如果sessionID不存在(一般是一个新的会话开启后第一次调用
request.getSession()方法),服务器就会创建一个session对象,给session对象分配
该session对象指定一个名叫JSESSIONID的cookie中,cookie中就保存sessionID,并
将cookie保存到浏览器。
2>如果sessionID存在,服务器就会通过sessionID在session缓存中查找对应的session
对象,如果没有查找到(会话没关闭但是session对象被销毁了),服务器就会创建一个
session对象,还会session对象新分配个sessionid,把session对象保存到session缓存中,
并给该session对象指定一个名叫JSESSIONID的cookie中,cookie中还是保存sessionID,
并将cookie保存到浏览器。
3>如果sessionID存在,服务器也通过sessionID在session缓存中找到了对应的
session对象,那么服务器就不再创建session对象了,直接将找到的session对象
返回(是在一个会话,且session对象没有被摧毁,且是二次以及二次以后调用
request.getSession())。
所以在一个会话中,服务器不会马上创建session对象,而是在第一次调用
request.getSession()方法获取session()对象时才会创建session对象。
5.为什么同一个session在一个会话范围内被共享?
因为当一个会话开启时,服务器会创建一个新的session对象,将session对象保存在
session缓存,同时给改session对象指定了一个sessionID保存在名为JSEEIONID
的cookie中,并将改cookie保存在了浏览器中。而这个cookie的maxAge属性值默认为
-1,即只在浏览器内存中存在,只要不关闭浏览器那么该cookie就一直存在。
而下次请求时,再次执行request.getSession()方法时,服务器可以从请求对象request中
获取到名为JSEESIONID的cookie,进而拿到sessionID,再通过该sessionID从session
缓存中再次拿到该sessionID对应的session对象,所以与上次请求使用的是同一个session
对象。
6.细说request.getSession()方法:
1>reqeust.getSession(false):如果从请求中获取的名叫JSESSIONID的
cookie中没有获取到sessionID,或获取到的sessionID在session缓存中没有对应的
session对象,服务器不会创建新的session对象,返回null。
2>request.getSession()或request.getSession(true):会创建新的session对象。
7.Servlet和jsp创建session的区别:
1>创建一个Servlet,在Servlet中没有调用request.getSession()方法,那么服务器
也就谈不上request请求对象中获取名为JSESSIONID的cookie拿到sessionID,
就更谈不上创建session对象。那么请求该Servlet时,服务器也不会给浏览器
响应名为JSESSION的cookie;只用当在Servlet中调用了request.getSession()
方法时,服务器才会从请求对象request中获取名为JSESSIONID的cookie,再从
该cookie中拿到sessionID。如果该sessionID存在,那么直接从session缓存中获取
对应的session对象;如果该sessionID不存在,请求该Servlet,服务器才会创建
session对象,并给浏览器响应名为JSESSION的cookie,并保存sessionID。
2>而不管请求任何jsp时,每个jsp页面对应的Servlet中都调用了
request.getSession()方法,服务器都会从请求request对象中获取名为
JSESSIONID的cookie,并cookie中去获取sessionID。如果该sessionID存在,
则服务器直接从session缓存中直接获取其对应的session对象;如果该sessionID
不存在,那么服务器就会session对象,并给浏览器相应名为JSESSIONID的cookie,
并保存sessionID。
这也就是之前为什么我们请求任何一个新的jsp页面,通过HttpWatch拦截都能看
到响应协议中服务器为浏览器响应了名为JSESSIONID的cookie。而请求一个新
的Servlet在不调用request.getSession()的情况下,响应协议中不会看到服务器
给浏览器响应名为JSESSIONID的cookie的原因。
也是为什么Servlet获取session对象必须使用request.getSession()方法,而jsp可以直接
使用的原因。
HttpSession的其它方法
1>String | getId()获取sessionID
sessionID是一个32位长的16进制字符串,其实底层是使用
java.util.UUID类生成的一个随机字符串,并能保证每次生成的字符串不同。
2>boolean | isNew()判断session是否为新的
在一个会话中,当第一次调用request.getSession()方法获取session对象时,
服务器会创建session对象,但这时服务器还没有保存sessionID的名叫JSESSIONID的
cookie响应给客户端浏览器时,这时的session状态为新。
3>int | getMaxInactiveInterval()获取session可以的最大不活动时间(秒)。
默认为30分钟,当该session在30分钟内没有使用,那么服务器会在session
缓存中将该session移除。
在web.xml中配置session的最大不活动时间:
<session-config>
<session-timeout>30</session-timeout>
</session-config>
4>void | invalidate()让session失效。
调用该方法会让当前session失效,当session失效后,再次使用
request.getSession()方法获取session对象时,服务器会创建一个
新的session对象,并为其指定新的sessionID,并给客户端浏览器
响应新的JSESSIONID的cookie。
该方法一般用作当用户退出登录时,让当前session失效,防止用户
退出登录后,受限页面仍可被直接访问的问题。
9.URL重写
前面说过session的底层依赖于cookie,其目的是让客户端发送请求时向服务器自动归还名为
JSESSIONID的cookie,服务器再从cookie中拿sessionId,再通过sessionId从session缓冲区
中拿到对应的session对象,这样就能保证同一个会话共享同一个session对象。
但是如果客户端禁用了cookie,那么服务器就无法拿到名为JSESSIONID的Cookie,也就拿
不到sessionId,更拿不到session对象了。
所以也可以通过URL重写来替代cookie向服务器归还sessionId,其本质就是:
1>在超链接、表单等请求路径中添加一个特殊的请求参数jessionid,参数值就是sessionId。
代替cookie向服务器归还sessionId。
2>服务器就可以通过请求参数jsessionid获取sessionId,再通过sessionId从session缓冲区
获取到对应的session对象
3>Reponse.encodeURL(url)方法会智能的对参数url进行重写:
1)当请求中归还了名为JSESSIONID的cookie时,那么该方法不会重写参数url,
服务器还是通过名为JSESSIONID的cookie获取sessionId,进而获取到session
对象
2)当请求没有归还名为JSESSIONID的cookie时,那么该方法就会自动在请求url的
后面加上参数jsessionid值为sessionid。那么服务器就会通过请求参数jessionid获取sessionid
进而获取到session对象。