Cookie和session入门到进阶
Cookie的快速入门
Cookie是客户端的传话技术,它是服务器存放在浏览器的一小份数据,浏览器以后每次访问服务器时都会这小分据携带到服务器个人理解cookie是服务器第一次发送过来的仍后浏览器给保存上
相关的API
-
创建一个Cookie 对象 (cookie只能保存字符串数据,且不能保存中文)
new Cookie(String name,String value); -
把cookie写回浏览器
·
response.addCookie(cookie); -
获取浏览器带过来的所有Cookie
request.getCookies();//得到所有的cookie对象,是一个数组,开发根据key等到目标cookie
-
cookie的API
cookie.getName();//返回cookie中设置的keycookie.getValue;//返回cookie中设置的value入门代码
package itheima.day24_Cookie_session_jsp; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class TestDemo01 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("cookies:::来了一个请求"); //获取cookis对象 if (req.getCookies().length!=0){ Cookie[] cookies = req.getCookies(); for (Cookie cookie1 : cookies) { //获取所有的cookie if(cookie1.getName().equals("name")){ String value = cookie1.getValue(); System.out.println(value); } } } //New 一个COokie创建一个新的cookie Cookie cookie = new Cookie("name","pyb"); Cookie cookie2 = new Cookie("password","123"); resp.addCookie(cookie2); //写入里浏览器里面去 resp.addCookie(cookie); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }4.小结
-
cookie特点
- Cookie保存在客户端(浏览器端的)
- 第一次请求的时候, 没有Cookie的, 先由服务器写给浏览器.
- Cookie里面只能保存字符串, 大小有限制
-
cookie相关API
- new Cookie(String name,String value); 创建Cookie
- response.addCookie(cookie); 把Cookie写给浏览器
- request.getCookies(); 获得所有的Cookie对象
- cookie.getName() 获得Cookie的key
- cookie.getValue() 获得Cookie的value
Cookie本质是请求头,响应头
-
为了方便把获取想要的cookis抽出来工具类中
package itheima.beanUntils;
import javax.servlet.http.Cookie;
public class IfCookie {
/**
* 从cookie的数组里面查找出来我们想要的目标cookie
* @param cookies cookie的数组
* @param key 想要获取的cookie的名字
* @return cookie的对象
*/
public static String getCookieUntil(Cookie[] cookies,String key){
//cookies数组是否为空
if(cookies!=null){
for (Cookie cookie1 : cookies) {
//获取所有的cookie
if(cookie1.getName().equals("name")){
String value = cookie1.getValue();
return value;
}
}
}
return null;
//如果没有找到就直接返回null
}
}
知识点-cookis进阶
cookie的有效时长和路径分析
-
会话级别临时性cookie默认
在默认的情况下,当浏览器进程结束(浏览器关闭,会话结束)的时候,cookie就会消失。
-
持久性cookie
- 设置cookie.setMaxAge(int expiry) 时间是秒
-1:默认。代表Cookie数据存到浏览器关闭(保存在浏览器文件中)。
正整数:以秒为单位保存数据有有效时间(把缓存数据保存到磁盘中)
0:代表删除Cookie.如果要删除Cookie要确保路径一致。告诉浏览器,立即删除掉这个cookie .
代码
package itheima.day24_Cookie_session_jsp;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/Demo02")
public class ServletDmo02 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//一个会话进来了
System.out.println("我进来了");
//设置一个会话
Cookie cookie = new Cookie("name", "pyb");
//这个cookie不设置长度
response.addCookie(cookie);
Cookie cookie1 = new Cookie("key","username");
//设置时间
cookie1.setMaxAge(60*60*7);
response.addCookie(cookie1); // 设置有效期,单位是秒 如果是谁知7天
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
cookie有效路径(了解)
setPath(String url); 设置路径
- 保证不会携带别的网站/项目里面的cookie到我们自己的项目 不会吧其他servlet设置的cookie带到现在的这个servlet来。
- 如果路径不一样, cookie的key可以相同 , 在相同路径下,重复一样的cookie的key,他们的值会覆盖的。
- 保证自己的项目可以合理的利用自己项目的cookie
-
默认路径,例如:
-
访问http://localhost:8080/web18A_Cookie/demo01; cookie默认路径 /web18A_Cookie
-
访问http://localhost:8080/web18A_Cookie/aaa/demo01; cookie默认路径 /web18A_Cookie/aaa
-
访问http://localhost:8080/web18A_Cookie/aaa/bbb/demo01; cookie默认路径 /web18A_Cookie/aaa/bbb
-
-
随带Cookie需要的条件: **只有当访问资源的url包含此cookie的有效path的时候,才会携带这个cookie;反之不会. **
-
eg: 设置cookie的路径 /demo02
下次访问路径:http://localhost:8080/day30a-cookie/demo02/ccc; cookie是可以带过来
下次访问路径:http://localhost:8080/day30a-cookie/demo03; cookie带不过来
-
-
cookie的路径通常设置 / 或者 /发布项目名设置的有效是 /day30a-cookie. 当前项目下的Servlet都可以使用该cookie. 一般这么设置: cookie.setPath(request.getContextPath());
只要是当前项目里面的资源 路径必须包含项目名路径.
代码
package itheima.day24_Cookie_session_jsp;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/Demo02")
public class ServletDmo02 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//一个会话进来了
System.out.println("我进来了");
//设置一个会话
Cookie cookie = new Cookie("name", "pyb");
//这个cookie不设置长度
response.addCookie(cookie);
Cookie cookie1 = new Cookie("key","username");
//设置时间
cookie1.setMaxAge(60*60*7);
response.addCookie(cookie1); // 设置有效期,单位是秒 如果是谁知7天
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
cookie保存中文
cookie不能保存中文,但是可以把中文字符经过编码 之后保存后续再经过 解码还原成正常的中文即可
URLEncode.encode(value,"utf-8")//存入的时候通过utf-解码
URLDecode.decode(value,"uft-8")//取出通过utf-解码
代码
package itheima.day24_Cookie_session_jsp;
import itheima.beanUntils.IfCookie;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Base64;
@WebServlet("/ServletDemo04")
public class ServletDemo04 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//
System.out.println("进来了一条数据");
//获取数据 第一种数据方式
/* Cookie[] cookies = request.getCookies();
String name = IfCookie.getCookieUntil(cookies, "name");
if (name!=null){
Base64.Decoder decoder = Base64.getDecoder();
byte[] decode = decoder.decode(name);
System.out.println(new String(decode));
}*/
//第二种方式
Cookie[] cookies = request.getCookies();
String name = IfCookie.getCookieUntil(cookies, "name");
if (name!=null){
String decode = URLDecoder.decode(name, "utf-8");
System.out.println(decode);
}
/* //第一种方式利用BASe64编码
Base64.Encoder urlEncoder = Base64.getUrlEncoder();
String string = urlEncoder.encodeToString("hello".getBytes());
Cookie cookie = new Cookie("name",string);
response.addCookie(cookie);*/
//第二种编码方式
String en = URLEncoder.encode("你好李焕英", "UTF-8");
Cookie cookie = new Cookie("name",en);
response.addCookie(cookie);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
URLEncode.encode(value,"utf-8");//存入的时候(先通过utf-8编码)
URLDecode.decode(value,"utf-8");//取出 (通过utf-8解码)
接下来我们实现一个小案例,记录用户各自上次访问的时间
package itheima.day24_Cookie_session_jsp;
import itheima.beanUntils.IfCookie;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Time;
import java.text.SimpleDateFormat;
import java.util.Date;
@WebServlet("/sca")
public class ServletCookieAnli extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
//获取值
Cookie[] cookies = request.getCookies();
String time = IfCookie.getCookieUntil(cookies, "time");
if(time!=null){
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String value = dateFormat.format(new Date(Long.parseLong(time)));
response.getWriter().write("<h2>您上一次访问的时间:"+value+"</h2>");
}
//完成上次访问时间的小案例
//首先设置cookies存数据获取时间
long timeMillis = System.currentTimeMillis();
Cookie cookie = new Cookie("time",String.valueOf(timeMillis));
//设置时间长度
cookie.setMaxAge(60*60*7);
//存好放入res
response.addCookie(cookie);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
知识点-session概述
3.1session概述
session是服务器端的技术。服务器为每一个浏览器开辟一块内存空间,即session对象。由于session对象是每一个浏览器特有的,所有用户的记录可以存放在session对象中。同时,每一个session对象都对应一个sessionId,服务器把sessionId写到cookie中,再次访问的时候,浏览器把sessionId带过来,找到对应的session对象
session 是一种基于cookie的会话技术。
session是保存在服务器端的原则上大小是没有限制的,session可以存在基本数据类型,集合对象
入门案例
package itheima.project.colltion;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/demo08")
public class ServletSession extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取session
HttpSession session = request.getSession();
//可以查看session的id
String id = session.getId();
System.out.println(id);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
我们不难发现cookies是从服务器拿的然后存到浏览器中和session是从request中拿的存到服务器中
4.小结
- session是服务器端的技术, 数据保存在服务器端的
- 只有在服务器端调用了requet.getSession()的时候, 才有session产生 ,才会开辟空间
- session基于cookie的
- 创建session的同时 生成sessionId, 服务器自动通过Cookie的方式写给浏览器, 浏览器自己保存
- 下次的话 浏览器携带cookie(SessionId)找到对应的session使用了
session 的API
- request.getSession() 获得session(如果第一次调用的时候其实是创建session,第一次之后通过sessionId找到session进行使用)
- object.getAttribute(String name);获取值
- void setAttribute(String name, Object value) ;存储值
- void removeAttribute(String name) ;移除
代码案例
package itheima.day24_Cookie_session_jsp;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/ServletDemo1")
public class ServletDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取数据
HttpSession session = request.getSession();
//设置参数
session.setAttribute("name","pyb");
session.setAttribute("password","12344");
//3. 取数据
System.out.println("address=" + session.getAttribute("name"));
System.out.println("className=" + session.getAttribute("password"));
//4. 删除数据
session.removeAttribute("name");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
4.小结
-
Session基本使用: 作为域对象存取数据 范围: 一次会话(多次请求, 用户各自的) 不同的浏览器session不一样
- Object getAttribute(String name) ;获取值
- void setAttribute(String name, Object value) ;存储值 如果存值的话,已经存在了name, name后面一次操作的value值会覆盖前面的value值。
- void removeAttribute(String name) ;移除
-
浏览器关闭了, session使用不了, 是session销毁了吗?
session没有销毁. 因为关闭浏览器是客户端的行为, session是服务器端里面的一块内存空间。关闭浏览器怎么会影响到session的销毁呢?
session基于cookie, sessionId保存到cookie里面的, 默认情况下cookie是会话级别,浏览器关闭了cookie就是消失了,也就是说sessionId消失了, 从而找不到对应的session对象了, 就不能使用了.
解决: 自己获得sessionId, 自己写给浏览器 设置Cookie的有效时长, 这个Cookie的key必须:
JSESSIONID -
session的生命周期
-
创建:
第一次调用getSession()的时候创建
-
销毁:
- 超时了销毁(session默认有有效期(30分钟),过了有效期就销毁了。) 自动销毁
- 手动销毁, 调用方法: invalidate();
- 服务器异常关闭: 蓝屏,突然停电...
- 关闭服务器,会销毁session吗? 不会销毁里面的数据。下次再启动服务器还是能够拿到以前的数据的。
-
-
面试的问题:
-
浏览器关闭,session销毁了吗? 没有
-
那么为什么我们打开浏览器之后,访问不到以前的数据了呢? 因为cookie销毁了,cookie里面有session的ID
-
如果我希望打开浏览器重新访问之后,还能获取到以前的值,怎么办?
需要手动设置cookie。
-
代码案例
package com.itheima.demo2_session;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
@WebServlet("/session04")
public class DemoSession04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("session04:::来了一个请求~~");
//赋值然后取值。
HttpSession session = req.getSession();
session.setAttribute("username" , "张三");
System.out.println("sesison04==="+session.getAttribute("username"));
//如果希望一会关闭浏览器之后,再来访问session05 还能取到04 存的值,那么需要手动设置cookie
//cookie的name不能乱写! 必须是固定写法!!!!
Cookie cookie = new Cookie("JSESSIONID" , session.getId());
cookie.setMaxAge(60*60*24*7);
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
相信大家都cookies和session有很强的认知了
那我们看一个三个域对象比较、
| 域对象 | 创建 | 销毁 | 作用范围 | 应用场景 |
|---|---|---|---|---|
| ServletContext | 服务器启动 | 服务器正常关闭/项目从服务器移除 | 整个项目 | 记录访问次数,聊天室 |
| HttpSession | 没有session 调 用request.getSession()方法 | session过期(默认30分钟)/调用invalidate()方法/服务器异常关闭 | 会话(多次请求) | 验证码校验,保存用户登录状态等 |
| HttpServletRequest | 来了请求 | 响应这个请求(或者请求已经接收了) | 一次请求 | servletA和jsp(servletB)之间数据传递(转发的时候存数据) |
想看钝化的文件的位置,请参考idea里面的日志输出:
Using CATALINA_BASE: "C:\Users\xiaomi\AppData\Local\JetBrains\IntelliJIdea2020.1\tomcat\Tomcat_8_5_27_javaweb110_3"目录查看
-
如果是正常关闭服务器,
把session钝化到服务器磁盘上,再次启动,把磁盘上的文件活化到内存里面
Session钝化:把内存中的session序列化到硬盘上 Session活化:从硬盘上读取序列化的session到内存中
了解就好了
3.2三个域对象怎么选择?
三个域对象怎么选择?
记住一个准则: 够用就好。
一般情况下, 最小的可以解决就用最小的.
但是需要根据情况(eg: 重定向, 多次请求, 会话范围, 用session; 如果是转发,一般选择request)
谢谢小伙伴们,欢迎留言哦

浙公网安备 33010602011771号