Cookie和session
一.Cookie和Session
1.业务场景
- 在登录时要记录账号
- 在查询等功能页面上显示此账号
2.错误的解决方案
1)使用request记录账号
- 登录是一个请求,使用一个reqeust
- 查询是另一个请求,使用另一个request
不同的请求无法通过request共享数据
2)使用config记录账号
- 开发项目时可能采用多个Servlet处理不同的请求
- 可能登录是一个Servlet,它使用一个config
- 可能查询是另一个Servlet,它使用另一个config
不同的Servlet无法通过config共享数据
3)使用context记录账号
- 浏览器和服务器是多对一的关系
- 服务器会给每个项目只创建唯一的context
- 多个浏览器都向这个对象中存数据,其key有冲突
使用一个对象无法给多个浏览器存储名称相同的数据
3.正确的解决方案(cookie/session可以在同一个浏览器间共享数据(有效路径下))
- 使用cookie或session存储数据
- 数据可以在多个请求之间共用
- 数据可以在多个Servlet之间共用
- 服务器会给每个浏览器创建一份cookie/session
上述3点由服务器保障
4.它们的区别
- cookie存储在浏览器上,服务器压力小,但数据不安全
- session存储在服务器上,服务器压力大,但数据安全

5.使用建议
- 重要的数据存入session
- 其他的数据存入cookie
三.Cookie
特点: 1:一个cookie只能存储一份数据(key-value)
2:只要浏览器不关闭,cookie就一直存在
3:cookie里存中文会报错,编码-->解码
1.案例

2.归纳
2.1基本语法
- 1.1如何创建cookie
Cookie c1 = new Cookie("code",code); - 1.2如何创建session
- 第一次访问session时服务器自动创建它,不需要我们创建
- 2.1如何获取cookie
-
Cookie[] cs = req.getCookies(); - 2.2如何获取session
-
HttpSession session = req.getSession(); - 3.1如何存值cookie
-
Cookie c1 = new Cookie("code",code); - 3.2如何存值session
-
//session中可以存任意类型的数据 session.setAttribute("code", code); - 如何修改cookie
![]()
![]()
2.2扩展点
- 如何修改生存时间
1 //设置cookie的生存时间 2 c1.setMaxAge(600000); - 如何存中文
1 //向cookie中存中文 2 Cookie c2 = new Cookie("city", 3 URLEncoder.encode("北京", "utf-8")); 4 res.addCookie(c2);1 String value = 2 URLDecoder.decode( 3 c.getValue(),"utf-8"); - 如何修改有效路径
1 //设置cookie的有效路径 2 Cookie c3 = new Cookie("name","Tarena"); 3 c3.setPath("/jsp3"); 4 res.addCookie(c3);
web包下:loginServlet
1 package web;
2
3 import java.io.IOException;
4 import java.net.URLEncoder;
5
6 import javax.servlet.ServletException;
7 import javax.servlet.http.Cookie;
8 import javax.servlet.http.HttpServlet;
9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11
12 public class LoginServlet extends HttpServlet {
13
14 //相当于MainServlet.login()
15 @Override
16 protected void service(
17 HttpServletRequest req,
18 HttpServletResponse res) throws ServletException, IOException {
19 //接收传入的参数
20 String code = req.getParameter("code");
21 //存入cookie,给其他功能使用
22 //1.一个cookie对象中只能存一个数据
23 //2.所存的数据必须是字符串
24 //3.可以创建更多个cookie以保存更多的数据
25 Cookie c1 = new Cookie("code",code);
26 //设置cookie的生存时间
27 c1.setMaxAge(600000);
28 //将cookie存入response,在服务器响应时,
29 //会自动把cookie发送给浏览器.
30 res.addCookie(c1);
31 //向cookie中存中文
32 Cookie c2 = new Cookie("city",
33 URLEncoder.encode("北京", "utf-8"));
34 res.addCookie(c2);
35 //设置cookie的有效路径
36 Cookie c3 = new Cookie("name","Tarena");
37 c3.setPath("/jsp3");
38 res.addCookie(c3);
39 }
40
41 }
配置文件省略
index.servlet
1 package web;
2
3 import java.io.IOException;
4 import java.io.PrintWriter;
5 import java.net.URLDecoder;
6
7 import javax.servlet.ServletException;
8 import javax.servlet.http.Cookie;
9 import javax.servlet.http.HttpServlet;
10 import javax.servlet.http.HttpServletRequest;
11 import javax.servlet.http.HttpServletResponse;
12
13 public class IndexServlet extends HttpServlet {
14
15 //相当于MainServlet.toIndex()
16 @Override
17 protected void service(
18 HttpServletRequest req,
19 HttpServletResponse res) throws ServletException, IOException {
20 //浏览器再次访问此服务器时,会自动传入
21 //之前保存的cookie,现在获取此cookie.
22 Cookie[] cs = req.getCookies();
23 //将cookie中的数据显示到页面上
24 if(cs != null) {
25 res.setContentType(
26 "text/html;charset=utf-8");
27 PrintWriter out = res.getWriter();
28 for(Cookie c : cs) {
29 String value =
30 URLDecoder.decode(
31 c.getValue(),"utf-8");
32 out.println(
33 c.getName()+":"+value);
34 }
35 out.close();
36 }
37 }
38
39 }


cookie的缺点:

四.Session
特点: 1:浏览器第一次访问服务器时,服务器会给他创建一个session,服务器会使用cookie将Sid返回给浏览器,浏览器再次访问服务器时会传入Sid
2:多个请求可以共用同一个session
3:多个servlet可以共用同一个session
4:服务器会给每个浏览器创建一个session
5:session超时:30min
6:删除session对象的使用场景:注销/退出 session.invalidate()
1.案例

1 package web;
2
3 import java.io.IOException;
4
5 import javax.servlet.ServletException;
6 import javax.servlet.http.HttpServlet;
7 import javax.servlet.http.HttpServletRequest;
8 import javax.servlet.http.HttpServletResponse;
9 import javax.servlet.http.HttpSession;
10
11 public class LoginServlet extends HttpServlet {
12
13 //相当于MainServlet.login()
14 @Override
15 protected void service(
16 HttpServletRequest req,
17 HttpServletResponse res) throws ServletException, IOException {
18 //接收参数
19 String code = req.getParameter("code");
20 //存入session
21 //第一次访问session时服务器自动创建它,
22 //当前登录就是第一次访问,就创建session
23 HttpSession session = req.getSession();
24 //session中可以存任意类型的数据
25 session.setAttribute("code", code);
26 //服务器向浏览器发送响应时,会自动创建
27 //一个cookie,并将SID存入此cookie,再
28 //将此cookie发送给浏览器.服务器会将
29 //此cookie的有效路径设置为项目.
30 }
31
32 }
1 package web;
2
3 import java.io.IOException;
4 import java.io.PrintWriter;
5
6 import javax.servlet.ServletException;
7 import javax.servlet.http.HttpServlet;
8 import javax.servlet.http.HttpServletRequest;
9 import javax.servlet.http.HttpServletResponse;
10 import javax.servlet.http.HttpSession;
11
12 public class FindCostServlet extends HttpServlet {
13
14 //相当于MainServlet.findCost()
15 @Override
16 protected void service(
17 HttpServletRequest req,
18 HttpServletResponse res) throws ServletException, IOException {
19 //获取旧的session,此session是在
20 //登录请求中服务器自动创建的.
21 HttpSession session = req.getSession();
22 String code = (String)
23 session.getAttribute("code");
24 //输出数据
25 res.setContentType(
26 "text/html;charset=utf-8");
27 PrintWriter out = res.getWriter();
28 out.println(code);
29 out.close();
30 }
31
32 }


session验证码:
MainServlet
} else if("/createImg.do".equals(path)) {
//生成验证码
createImg(req, res);
1 protected void createImg(
2 HttpServletRequest req,
3 HttpServletResponse res)
4 throws ServletException, IOException {
5 //创建验证码及图片
6 Object[] objs = ImageUtil.createImage();
7 //将验证码存入session
8 HttpSession sn = req.getSession();
9 sn.setAttribute("imgCode", objs[0]);
10 //将图片输出给浏览器
11 res.setContentType("image/png");
12 OutputStream os = res.getOutputStream();
13 ImageIO.write(
14 (BufferedImage) objs[1], "png", os);
15 os.close();
16 }
封装生成数字,子母等验证码
1 package util;
2
3 import java.awt.Color;
4 import java.awt.Font;
5 import java.awt.Graphics;
6 import java.awt.image.BufferedImage;
7 import java.io.FileOutputStream;
8 import java.io.IOException;
9 import java.io.OutputStream;
10 import java.util.Random;
11 import javax.imageio.ImageIO;
12
13 public final class ImageUtil {
14
15 // 验证码字符集
16 private static final char[] chars = {
17 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
18 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
19 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
20 // 字符数量
21 private static final int SIZE = 4;
22 // 干扰线数量
23 private static final int LINES = 5;
24 // 宽度
25 private static final int WIDTH = 80;
26 // 高度
27 private static final int HEIGHT = 40;
28 // 字体大小
29 private static final int FONT_SIZE = 30;
30
31 /**
32 * 生成随机验证码及图片
33 * Object[0] : 验证码字符串 String
34 * Object[1] : 验证码图片 BufferedImage
35 */
36 public static Object[] createImage() {
37 StringBuffer sb = new StringBuffer();
38 // 1.创建空白图片
39 BufferedImage image = new BufferedImage(
40 WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
41 // 2.获取图片画笔
42 Graphics graphic = image.getGraphics();
43 // 3.设置画笔颜色
44 graphic.setColor(Color.LIGHT_GRAY);
45 // 4.绘制矩形背景
46 graphic.fillRect(0, 0, WIDTH, HEIGHT);
47 // 5.画随机字符
48 Random ran = new Random();
49 for (int i = 0; i <SIZE; i++) {
50 // 取随机字符索引
51 int n = ran.nextInt(chars.length);
52 // 设置随机颜色
53 graphic.setColor(getRandomColor());
54 // 设置字体大小
55 graphic.setFont(new Font(
56 null, Font.BOLD + Font.ITALIC, FONT_SIZE));
57 // 画字符
58 graphic.drawString(
59 chars[n] + "", i * WIDTH / SIZE, HEIGHT / 2);
60 // 记录字符
61 sb.append(chars[n]);
62 }
63 // 6.画干扰线
64 for (int i = 0; i < LINES; i++) {
65 // 设置随机颜色
66 graphic.setColor(getRandomColor());
67 // 随机画线
68 graphic.drawLine(ran.nextInt(WIDTH), ran.nextInt(HEIGHT),
69 ran.nextInt(WIDTH), ran.nextInt(HEIGHT));
70 }
71 // 7.返回验证码和图片
72 return new Object[]{sb.toString(), image};
73 }
74
75 /**
76 * 随机取色
77 */
78 public static Color getRandomColor() {
79 Random ran = new Random();
80 Color color = new Color(ran.nextInt(256),
81 ran.nextInt(256), ran.nextInt(256));
82 return color;
83 }
84
85 public static void main(String[] args) throws IOException {
86 Object[] objs = createImage();
87 BufferedImage image =
88 (BufferedImage) objs[1];
89 // /home/soft01/x.png
90 OutputStream os =
91 new FileOutputStream("d:/x.png");
92 ImageIO.write(image, "png", os);
93 os.close();
94 }
95
96 }
1 <td class="login_info">验证码:</td>
2 <td class="width70"><input name="code" type="text" class="width70" /></td>
3 <!--在路径后面加上随机数,是为了欺骗浏览器,让它以为路径变了-->
4 <td><img src="createImg.do" onclick="this.src='createImg.do?x='+Math.random();" alt="验证码" title="点击更换" /></td>
5 <td><span class="required"></span></td>
总结:cookie和session的作用:
1.通俗的描述:
它们内部存储的数据满足如下规则:
1)这些数据在不同的请求中可以共用
2)这些数据在不同的servlet中可以共用
3)每个浏览器都有一组这样的数据
2.专业的描述:
1)http协议是无状态协议,即服务器没有记住浏览器,cookie和session就是用来管理状态,让服务器记住浏览器
2)状态:浏览器曾经访问过服务器的证据(数据)
温壶月光当茶饮



浙公网安备 33010602011771号