http怎样保持有状态?
HTTP协议的特点
HTTP协议是无状态的协议,发送的请求不记录用户的状态,不记录用户的信息。就相当于它被访问了2次,不知道是哪两人访问的,或者是一个人访问两次。
正是因为HTTP协议的这一特点,用户的活动发生在多个请求和响应之中,作为web服务器,必须能够采用一种机制来唯一地标识一个用户,同时记录该用户的状态。比如说我们平时上的qq.可以设置登录状态,记住密码,之后我们在一段时间内就可以不用输入密码直接输入,那么Http协议是无状态的,我们怎么可以让他记住我们的状态呢,就是通过会话跟踪技术
什么是会话:
就像我和一个人之间的对话
会话跟踪技术有哪几种?
Cookie Session 隐藏表单域(hidden) URL重写
什么是Cookie:
Cookie的中文意思是点心的意思
Cookie是保存到客户端的一个文本文件,与特定客户相关。
Cookie是一种由服务器发送给客户的片段信息,存储在客户端浏览器的内存中或硬盘上,cookie存活在本地,
在客户随后对该服务器的请求中发回它。
Cookie以“键-值”对的形式记录会话跟踪的内容,服务器利用响应报头set-cookie来发送cookie信息。
创建cookie
创建Cookie:new Cookie(name,value)
可以使用Cookie 的setXXX方法来设定一些相应的值
setName(String name)/getName()
setValue(String value)/getValue()
setMaxAge(int age)/getMaxAge()
利用HttpServletResponse的addCookie(Cookie)方法将它设置到客户端
利用HttpServletRequest的getCookies()方法来读取客户端的所有Cookie,返回一个Cookie数组
cookie的分类
Cookie分两种 放在内存中 一旦浏览器关闭 就消失了
Cookie c1=new Cookie("","");
response.addCookie(c1);
一种是属于文本 有生命周期的
可以通过serMaxAge(600);这个方法设置 毫秒为单位 表示这个cookie的有效时间
保存到硬盘上的cookie可以在多个浏览器之间共享,也就是说,两个浏览器在访问同一个url时,使用的是同一个cookie信息。
cookie的缺点
Cookie对用户是透明的,并且保存在磁盘上,持久性高,可以长时间的跟踪用户,了解用户上网的习惯,并且保存用户的名和密码等敏感信息有很大的安全隐患,而用户在网上的一举一动,就有可能成为某些网站的赚钱机会,这就会造成一些隐私权和安全性方法的问题。
而且我们也可以在浏览器中禁用cookie,就可以阻止所有的cookie,那么只要跟cookie相关的操作就失效了
cookie的应用1
设置cookie
Cookie cookie = new Cookie("Session-Cookie-" + i, "Cookie-Value-S" + i);
response.addCookie(cookie);
// 设置cookie的有效时间 单位为毫秒
cookie.setMaxAge(600);
response.addCookie(cookie);
}
读取客户端的Cookie
Cookie[] cookies = request.getCookies();
if (cookies != null) {
Cookie cookie;
for(int i=0; i<cookies.length; i++) {
cookie = cookies[i];
out.println("<TR>\n" +
" <TD>" + cookie.getName() + "</TD>\n" +
" <TD>" + cookie.getValue() + "</TD></TR>\n" );
}
}
out.println("</TABLE></BODY></HTML>");
}
}
session
客户端可以阻止服务器写入cookie 所以说cookie不太可靠 另外也不安全
更安全的是基于session的HttpSession对象
服务器为每个会话创建一个HttpSession对象
– 每个会话对象都有一个唯一的ID
– 把用户的数据保存在相应的HttpSession对象内
原理:
用户第一次发送请求的时候,服务器创建一个HttpSession对象,并把该对象的id返回给用户,同时服务器在内存中开辟一空间,用来保存该对象数据,服务器将此id发送回客户端做出响应;用户第二次发送请求的时候把id一起发送给服务器,服务器根据id号寻找相应的数据。
创建和使用session
会话的创建
使用HttpServletRequest 的 getSession() 方法创建会话,
获取session对象
两个方法:getSession();(=getSession(true);) getSession(boolean b);,
HttpSession session = request.getSession(true);
true: 返回与当前关联的会话,如果没有就创建后将其返回
false: 返回与当前关联的会话,如果没有返回null
使用session
session.setAttribute(String param,Object value);存值
session. getAttribute(String param);取值
session的生命周期
session的创建
浏览器访问服务器时,服务器为每个浏览器创建不同的session对象
session的关闭
调用session. invalidate()方法,使session对象失效(安全退出)
访问时间间隔大于非活动时间间隔, session对象失效
关闭浏览器时,session对象失效(也相当于第二种现象)
可以设置session的有效时间,服务器默认30分钟。
一般点击退出的时候,会调用invalidate()这个方法
生命周期总结:从一个客户端打开浏览器并连接到服务器开始,到客户端关闭浏览器离开这个服务器为止,或调用方法主动卸载session对象,或session对象存在时间超时后被自动卸载,在这期间被称为一个会话 。
每个客户端拥有自己独立的session对象
session与cookie的区别
1.cookie会把信息记录在客户端 就是本地
Session会记录在服务器端,服务器端创建sessionid后,需要把sessionid保存在客户端,就是保存到cookie中,可以采用cookie或url重写的方式保存。
如果cookie被禁用了,cookie不好用,session就会不好用
2.保存sessionid的cookie在关闭浏览器后就删除了,不能在多个浏览器中共享。而普通的cookie在关闭浏览器后再次打开时,仍然存在,可以在多个浏览器进程间共享。
解释: 通常将用于会话跟踪的cookie叫做会话cookie,在servlet规范中,用于会话跟踪的cookie名字必须为JSESSIONID,通常保存在浏览器的内存中。所以在内存中得cookie不能被不同的浏览器共享。对于保存在磁盘中得cookie,因为是在外部的存储设备存储,所以可以再多个浏览器进程中共享。
3.cookie只能写文本 有长度限制 4096字节 session没有限制
误区:很多人认为“浏览器一旦关闭,session就消失了”,是错误的!
主要是因为保存sessionid的cookie是存储在浏览器内存中,一旦浏览器关闭,cookie将被删除,sessioinid也丢失了。再次打开时,没办法找到之前的sessionid,所以肯定会创建一个新的session了。而这个时候先前的session是仍然存在的,直到session失效,才会被服务器消除。
比如:顾客在超市购物存包,购物完毕,忘了取包就走了,但存包处的人不知道顾客走了,所以必须让柜子继续使用存放原来顾客的东西,直到长时间没人来取,工作人员才会消除柜子。
URL重写
这种使用session保存用户信息的方式,我们是通过在客户端浏览器中保存了一个sessionid(其实就是cookie原理)来实现会话跟踪,现在我们在浏览器中禁用cookie,看看还能正常运行么?
设置完后,登录后,还提示没登陆!
访问TestServlet时,发现每次刷新都是1,都是新的sessionid。
这都是因为禁用了cookie,服务器无法从客户端获取sessionid了,那每次请求都会创建一个新的session。
这样,当用户禁用cookie后,session机制也失效了,自然无法实现跟踪了,我们需要使用URL重写机制对用户会话跟踪。
将URL传给response.encodeURL处理。
l 如果服务器使用cookie, 它原封不动地返回URL。
l 如果服务器使用URL重写,它将会话信息附加到URL上。
l 例如:
String url = "order-page.html";
url = response.encodeURL(url);
l 将URL传递给response.encodeRedirectURL(url)
当Cookie禁用 还想用Session时 可以通过URL重写实现会话跟踪