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)状态:浏览器曾经访问过服务器的证据(数据)

 

posted @ 2017-04-28 13:54  等你,在雨中  阅读(268)  评论(0)    收藏  举报