会话
会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。
一次会话指的是:就好比打电话,A给B打电话,接通之后,会话开始,直到挂断电话,该次会话就结束了,而浏览器访问服务器,就跟打电话一样,浏览器A给服务器发送请求,访问web程序,该次会话就已经接通,其中不管浏览器发送多少请求(就相当于接通电话后说话一样),都视为一次会话,直到浏览器关闭,本次会话结束。其中注意,一个浏览器就相当于一部电话,如果使用火狐浏览器,访问服务器,就是一次会话了,然后打开google浏览器,访问服务器,这是另一个会话,虽然是在同一台电脑,同一个用户在访问,但是,这是两次不同的会话。
Cookie
Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。
Cookie的内容主要包括:名字,值,过期时间,路径和域。路径与域一起构成cookie的作用范围。若不设置过期时间,则表示这
个Cookie的生命期为浏览器会话期间,关闭浏览器窗口,Cookie就消失。会话Cookie一般不存储在硬盘上而是保存在内存里,当然这种行为并不是规范规定的。若设置了过期时间,浏览器就会把Cookie保存到硬盘上,关闭后再次打开浏览器,这些Cookie仍然有效直到超过设定的过期时间。存储在硬盘上的Cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存里的Cookie,不同的浏览器有不同的处理方式。
注意:Cookie功能需要浏览器的支持。如果浏览器不支持Cookie或者把Cookie禁用了,Cookie功能就会失效。不同的浏览器采用不同的方式保存Cookie。
Cookie机制
Cookie技术是客户端的解决方案,Cookie就是由服务器发给客户端的特殊信息,而这些信息以文本文件的方式存放在客户端,然后客户端每次向服务器发送请求的时候都会带上这些特殊的信息。让我们说得更具体一些:当用户使用浏览器访问一个支持Cookie的网站的时候,用户会提供包括用户名在内的个人信息并且提交至服务器;接着,服务器在向客户端回传相应的超文本的同时也会发回这些个人信息,当然这些信息并不是存放在HTTP响应体(Response Body)中的,而是存放于HTTP响应头(Response Header);当客户端浏览器接收到来自服务器的响应之后,浏览器会将这些信息存放在一个统一的位置。自此之后,客户端再向服务器发送请求的时候,都会把相应的Cookie再次发回至服务器。而这次,Cookie信息则存放在HTTP请求头(Request Header)了。有了Cookie这样的技术实现,服务器在接收到来自客户端浏览器的请求之后,就能够通过分析存放于请求头的Cookie得到客户端特有的信息,从而动态生成与该客户端相对应的内容。通常,我们可以从很多网站的登录界面中看到“请记住我”这样的选项,如果你勾选了它之后再登录,那么在下一次访问该网站的时候就不需要进行重复而繁琐的登录动作了,而这个功能就是通过Cookie实现的。
//创建Cookie,采用键-值对形式
Cookie cookie = new Cookie("key", "value");
//设置Cookie持久化时间
cookie.setMaxAge(3600);
/*设置Cookie的携带路径
*默认情况下会在访问创建Cookie的web资源相同的路径都携带Cookie信息
*1、设置指定的Servlet携带信息,2、设置指定的工程携带信息,3、设置服务器部署的所有工程都携带信息*/
cookie.setPath("/JWDemo/CookieServlet2");//设置指定的Servlet携带Cookie信息
cookie.setPath("/JWDemo");//设置指定的项目携带Cookie信息
cookie.setPath("/");//设置整个服务器下部署的所有项目都携带Cookie信息
//删除Cookie信息只需要把Cookie持久化时间设置为0即可
cookie.setMaxAge(0);
//响应给浏览器
response.addCookie(cookie);
//Cookie信息的获取
Cookie[] cookies = request.getCookies();
if(cookies != null) {
for(Cookie cook:cookies) {
if(cook.getName().equals("key")) {
System.out.println("获取cookie信息成功"+cook.getValue());
response.getWriter().write(cook.getValue());
}
}
}
记录上一次登录时间
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setContentType("text/html;charset=UTF-8");
//获取当前日期
Date date = new Date();
//格式化日期形式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-mm-dd-hh:mm:ss");
String time = simpleDateFormat.format(date);
Cookie cookie = new Cookie("lastTime",time);
response.addCookie(cookie);
String lastTime = null;
Cookie[] cookies = request.getCookies();
if(cookies != null) {
for(Cookie cook:cookies) {
if(cook.getName().equals("lastTime")) {
lastTime = cook.getValue();
}
}
}
if(lastTime != null) {
response.getWriter().write("上次的登录时间为:"+lastTime);
}else {
response.getWriter().write("你是第一次登录");
}
}
Session
Session保存在服务器端,服务器一般把Session放在内存里,每个用户都会有一个独立的Session。如果Session内容过于复杂,当大量客户访问服务器时可能会导致内存溢出,因此Session里的信息应该尽量精简。
Session在用户第一次访问服务器的时候自动创建,需要注意只有访问JSP、Servlet等程序时才会创建Session,只访问HTML、IMAGE等静态资源并不会创建Session。如果尚未生成Session,也可以使用request.getSession(true)强制生成Session。
Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。用户每访问服务器一次,无论是否读写Session,服务器都认为该用户的Session“活跃(active)”了一次。
Session机制
Session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。当程序需要为某个客户端的请求创建一个Session时,服务器首先检查这个客户端的请求里是否已包含了一个Session标识(称为session id),如果已包含则说明以前已经为此客户端创建过Session,服务器就按照session id把这个Session检索出来使用(检索不到,会新建一个),如果客户端请求不包含session id,则为此客户端创建一个Session并且生成一个与此Session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。保存这个session id的方式可以采用Cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。一般这个Cookie的名字都是类似于SEEESIONID。但Cookie可以被人为的禁止,在Cookie禁用时经常被使用URL重写技术实现回传(还有一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器),就是把session id直接附加在URL路径的后面。
Session生命周期:Session作用范围默认在一次会话中,在一次会话中任何资源公用一个Session对象;第一次执行request.getSession()时自动创建Session;服务器非正常关闭时自动销毁Session;session过期或失败(默认30分钟),从最后一次操作结束时倒计时自动销毁Session;手动销毁;浏览器关闭,Session不会销毁
Session的超时时间为maxInactiveInterval属性,可以通过对应的getMaxInactiveInterval()获取,通过setMaxInactiveInterval(longinterval)修改。Session的超时时间也可以在web.xml中修改。另外,通过调用Session的invalidate()方法可以使Session失效。(注意:参数的单位为分钟,而setMaxInactiveInterval(int s)单位为秒。)
Tomcat中Session的默认超时时间为20分钟。通过setMaxInactiveInterval(int seconds)修改超时时间。可以修改web.xml改变Session的默认超时时间。例如修改为60分钟:
<session-config>
<session-timeout>60</session-timeout> <!-- 单位:分钟 -->
</session-config>
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//获取当前Session对象
HttpSession session = request.getSession();
session.setMaxInactiveInterval(300);//设置Session的最大保留时间,单位为秒
session.setAttribute("sessionKey", "这是session的值");//设置Session传递的值
}
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
HttpSession session = request.getSession();
Cookie cookie = new Cookie("JSESSIONID", session.getId());
cookie.setPath("/JWDemo");
cookie.setMaxAge(120);
response.addCookie(cookie);
String value = (String)session.getAttribute("sessionKey");
System.out.println(value);
System.out.println();
}
Cookie和Session的区别:
1、Cookie数据存放在客户的浏览器上,Session数据放在服务器上。
2、Cookie不是很安全,别人可以分析存放在本地的Cookie并进行Cookie欺骗,考虑到安全应当使用Session。
3、Session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用Cookie。
4、单个Cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个Cookie。
5、个人建议:将登陆信息等重要信息存放为Session;其他信息如果需要保留,可以放在Cookie中。