Cookie、Session
1.会话
会话:用户打开了一个浏览器,点击了很多超链接,访问很多web资源,然后关闭浏览器,这个过程可以称为会话。
一个网站怎么证明你来过?
客户端 服务端(存放网站)
- 服务端给客户端一个信件,客户端下次访问服务器带上信件就可以了;这个信件就是cookie。
- 服务端登记你访问过,下次来的时候直接匹配你;这种则是session
有状态会话:通过上面的描述,当我们再次访问这个浏览器,被匹配到的时候,这种就叫做有状态规划。
2.保存会话的两种技术
cookie
- 客户端技术(响应,请求)。
session
- 服务器技术,利用这个技术,可以保存用户会话信息,我们可以把信息或数据放在session中。
常见场景:当网站第一次登录成功进去后,下一次就不用再登录,可以直接访问自己的页面了。
3.Cookie
- 从请求中拿到cookie信息
- 服务器响应给客户端cookie
Cookie[] cookies = req.getCookies();//获得cookie
cookie.getName()//获得cookie中的key
cookie.getValue()//获取cookie中的value
new Cookie("lasttime", System.currentTimeMillis()+"");//新建一个cookie
cookie.setMaxAge(24*60*60);//设置cookie的有效期
resp.addCookie(cookie);//响应给客户端一个cookie
cookie一般会保存再本地的 用户目录下的appdata
注意:
- 一个cookie只能保存一个信息
- 一个web站点可以给浏览器发送多个cookie,最多存放20个cookie
- cookie大小有限制4kb
- 300个cookie是浏览器的上限
删除cookie的方式:
- 不设置有效期,关闭浏览器,自动失效
- 设置有效期为0(立马过期)
如果想传输中文数据但是担心会出现乱码问题,可以使用编码、解码来解决:
URLEncoder.encode("中文","utf-8");//需要传入数据的将中文编码
URLDecoder.decode("中文","utf-8");//需要取出数据的时候再将中文解码
测试如下:
//保存用户上一次访问的时间
public class Cookiedemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//服务器告诉你第一次访问的时间,把这个时间封装成一个信件,下次再访问的时候带来,就能知道你来过了。
//解决中文乱码
resp.setContentType("text/html");
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
PrintWriter out = resp.getWriter();
//Cookie,服务器端要从客户端这获取
Cookie[] cookies = req.getCookies();//从这里返回数组,说明cookie可能存在多个
//判断cookie是否存在
if(cookies != null){
//如果存在有cookie
out.write("您上次访问的时间是:");
for (int i =0;i<cookies.length;i++) {
Cookie cookie = cookies[i];
//获取cookie的名字
if(cookie.getName().equals("lasttime")){
//获取cookie的值
long lasttime = Long.parseLong(cookie.getValue());
Date date = new Date(lasttime);
out.write(date.toLocaleString());
}
}
}else{
out.write("这是您第一次访问本网站");
}
URLEncoder.encode("中文","utf-8");
URLDecoder.decode("中文","utf-8");
//服务端给客户端响应一个cookie
Cookie cookie = new Cookie("lasttime", System.currentTimeMillis()+"");
//cookie有效期为一天
cookie.setMaxAge(24*60*60);
resp.addCookie(cookie);
}
当第一次运行的时候不显示上一次运行的时间,当刷新再运行一次则会显示出上一次的时间,也可以在审查元素里面看到cookie的信息:
4.Session
什么是Session
- 服务器会给每个用户(浏览器)创建一个Session对象
- 一个Session独占一个浏览器,只要浏览器没关闭,这个Session就存在
- 用户登录之后,整个网站都可以都可以访问:保存用户的信息,保存购物车
Session和Cookie的区别
- cookie是把用户的数据写给用户的浏览器,浏览器保存
- Session把用户的数据写到用户独占Session中,session由服务器端保存(保存重要信息,减少服务器资源浪费)
- Session对象由服务器创建
- cookie是服务器创建的保存在客户端的浏览器中,东西存在客户端
如图:
用法如下:
- 通过Session存储对象数据:
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");//设置响应格式为html
//得到Session
HttpSession session = req.getSession();
//给Session存东西
session.setAttribute("name",new Person(1,"xiaopan"));//类似于key-value的模型一样,一个键对应一个值
//获取Session的id
String id = session.getId();
//判断session是不是新的
if(session.isNew()){
resp.getWriter().write("创建成功,id为" + id);
}else{
resp.getWriter().write("session已经存在,id为"+ id);
}
//在session创建的时候会将session存入cookie
//Cookie cookie = new Cookie("JSESSION",id);
//resp.addCookie(cookie);
}
通过测试也可发现,当浏览器打开时,Session就自动生成,并且保存在Cooike中
- 通过Session取出存储的数据
刚刚存进一个对象数据,则可以通过存在的键来找到存入的数据值,代码如下:
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");//设置响应格式为html
//得到Session
HttpSession session = req.getSession();
Person per = (Person) session.getAttribute("name");
System.out.println(per.toString());
}
结果如下:
-
删除Session的两种方法
- 手动删除:
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //解决乱码问题 req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); resp.setContentType("text/html;charset=utf-8");//设置响应格式为html //得到Session HttpSession session = req.getSession(); //移除数据元素 session.removeAttribute("name"); //手动注销session session.invalidate(); }
先得移除数据,再通过invalidate()方法来删除Session,删除Session相当于是关闭浏览器,需要再次打开浏览器才能生成新的Session。当删除Session之后,无法再获取原Session里面的数据,若是要获取,则会报错如下:
- 自动配置删除:
在web.xml中配置Session的有效期,有效期一过则会自动删除该浏览器的Session,然后新建一个:
<!-- 设置session默认失效时间-->
<session-config>
<!-- 15分钟后session自动失效-->
<session-timeout>15</session-timeout>
</session-config>