day033 cookie & session

1 案例1-显示上一次登陆的时间

1.1 需求

当用户访问我们的servlet时,如果是第一次访问,则提示是第一次访问,否则显示用户上一次的访问时间;

1.2 技术分析

需要记录用户上一次的访问时间,根据分析,request生命周期太短,不合适。servletContext生命周期太长,且是占用服务器的内存空间,使用会话技术,就可以解决这个问题。

1.3 会话概述

所谓的会话技术,就是浏览器与服务器的多次通信之间的一个技术。

按照会话技术的位置,可以分为客户端会话技术和服务器端会话技术。

客户端会话:

专业术语就是cookie技术。

Cookie就是由服务器负责创建的,由浏览器负责保存的一个小文件,这个小文件可以保存少量的信息。

服务器端会话技术:

Session是服务器端的会话技术,可以简单理解为是服务器为每一个浏览器创建的一个内存空间,用于保存与浏览器交互的过程中(会话)保存一些信息。

1.4 Cookie的作用

可以让多个request对象之间的数据共享(多次请求的数据共享);

1.5 Cookie的使用步骤

1:创建cookie的格式:

构造方法:Cookie(String name, String value)  

name就是cookie的名称;

value就是cookie要保存的值(不能含中文,否则语法报错)

2:将cookie交给浏览器的方法

response.addCookie(cookie对象);

3:获取cookie的方法:

Cookie[]   数组名 = reqesut.getCookies();

 

迭代数组,可以获取每一个cookie对象;

面向cookie对象,获取cookie的名称和值;

cookie对象.getName();

cookie对象.getValue();

1.6 Cookie的路径与保存时间

(1)路径

Cookie可以设置一个有效路径(有效路径就是表示这个cookie在访问哪儿的时候有效),如果不设置,默认就是当前路径的上一级路径。

例如:

http://localhost/day33/c1  默认cookie的路径就是:http://localhost/day33

手动修改路径:

Cookie对象.setPath(“/”);  代表的就是当前这个服务器,只要访问的是这个服务器地址,都会带着cookie。

(2)保存时间

设置cookie的存活时间:

Cookie对象.setMaxAge(int值代表的是秒);

如果参数小于0,代表当前会话有效(只要浏览器不关闭,一直有效)

如果参数等于0,代表响应给浏览器的时候cookie立刻死亡(删除cookie的时候使用)

如果参数大于0,代表响应给浏览器的时候开始计时,指定的秒数后cookie死亡。

1.7 设置cookie的域名

package com.itheima.demo01_cookie;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 设置cookie的域名
 */
public class Cookie_扩展 extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1:创建一个cookie对象
        Cookie c1 = new Cookie("c11","jack11");
        //2:设置路径
        //c1.setPath("/");//只要访问这个tomcat,都会带cookie
        //设置cookie的域名
        c1.setDomain(".abc.com");//地址的域名是本ip地址的www.abc.com的时候,携带这个cookie
        //3:设置cookie的存活时间
        c1.setMaxAge(50);
        //3:将cookie响应给浏览器
        response.addCookie(c1);
        response.getWriter().print("okk...");
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}

1.8 案例-纪录上一次的访问时间-步骤分析

1:编写一个servlet,先获取用户携带的cookie,如果有,则显示用户上一次登陆的时候;

2:如果没有显示第一次登陆;

3:更新cookie的值为本次登陆的时间;

参考代码:

/*
         *  1:编写一个servlet,先获取用户携带的cookie,如果有,则显示用户上一次登陆的时候;
            2:如果没有显示第一次登陆;
            3:更新cookie的值为本次登陆的时间;
         */
        //0:解决响应体的中文乱码
        response.setContentType("text/html;charset=utf-8");
        //1:编写一个servlet,先获取用户携带的cookie,如果有,则显示用户上一次登陆的时候;
        Cookie[] cs = request.getCookies();
        //1.5:为了解决有cookie,但不是hiscookie的情况,我们需要定义一个boolean类型的变量,用于解决逻辑文件
        boolean flag = false;//没有his   cookie
        if(cs!=null){
            for (Cookie c : cs) {
                String name = c.getName();
                //1:判断用户携带过来的cookie,是不是我们想要的cookie
                if("his".equals(name)){
                    //说明是我们要找的cookie
                    String value = c.getValue();
                    response.getWriter().println("亲,欢迎回来,您上一次的访问时间是:"+value);
                    flag=true;//说明找到了
                    break;
                }
            }
        }else{
            //什么cookie都没有
            response.getWriter().println("亲,您是第一次访问该网站...");
        }
        //判断flag
        if(!flag){
            有其他cookie,但是不是hiscookie
            response.getWriter().println("亲,您是第一次访问该网站...");
        }
        //3:更新cookie的值为本次登陆的时间;
        Cookie c = new Cookie("his",new Date().toLocaleString());
        c.setPath("/");
        c.setMaxAge(60*60);
        response.addCookie(c);

1.9 Cookie与缓存的区别

缓存:

是指服务器给浏览器响应的所有信息;(包含页面上的所有内容,例如:图片、文件、页面)

Cookie:

是指服务器让浏览器记住的一些很少量的信息(简单理解为只是缓存中的一小部分信息)

2 案例2--验证码

2.1 需求

当用户访问jsp页面的时候,显示一张验证码,并让用户填写一个验证码,当用户提交填写的验证码的时候在servlet中比对用户填写的验证码是否正确。

2.2 技术分析

1: 由于用户访问jsp时会发出一次请求,提交表单的时候会发出第二次请求,因此只能使用会话技术,保存真正的验证码的值,才可以在服务器端比较用户填写的验证码是否正确;

2: 会话技术有两种,一个是客户端会话技术(Cookie),另一个是服务器端会话技术(session)

本案例采用session技术实现。(因为cookie保存在客户端,不安全!!!,在开发中验证码绝对不能存在cookie里面,极度不安全,非常容易被破解。)

2.3 Session概述

Session是服务器端的会话技术,可以简单理解为是服务器为每一个浏览器创建的一个内存空间,用于保存与浏览器交互的过程中(会话)的一些信息。

2.4 Session的作用

1:保存验证码;

2:保存用户登录的对象;

3:用于与浏览器会话的数据保存;

4:session可以自动与cookie相互关联,完成会话技术(服务器可以自动识别每一个浏览器的身份)

2.5 Session使用原则

能少存尽量少存!因为服务器使用的是服务器的内存空间,能少存尽量少存,能让他快点死尽量让他快点死。

2.6 Session如何使用

Session主要用于保存信息,且session由服务器创建,保存在服务器端,程序员只能获取session并使用session,不能手动创建session。

 

常用API:

获取session:

request.getSession();

存值:

Session对象.setAttribite("属性名",属性值);

取值:

Session对象.getAttribite("属性名");

删除值:

Session对象.removeAttribute("属性名");

销毁session对象:

Session对象.invalidate();

设置存活时间:

Session对象.setMaxInactiveInterval(秒数);  (默认存活30分钟)

2.7 Session的生命周期问题(面试常用)

从session对象创建到session对象死亡;

(1)创建时机

1)这个浏览器在servlet中第一次使用session的时候会创建。

2)这个浏览器第一次访问jsp的时候,服务器也会为这个浏览器创建一个session对象。

(2)销毁时机

1)程序员调用invalidate方法(立刻销毁)

2)设置的存活时间到了(默认是30分钟)

3)服务器非正常关闭(例如突然断电)

注意事项:

1: 正常关闭服务器,session不会销毁,而是直接序列化到硬盘上,下一次服务器启动的时候,会重新创建出来。

2: 如果浏览器单方面关闭会话,服务器上对应的session不会死亡,但是会导致服务器给浏览器创建的JSESSIONID的cookie死亡,当cookie死亡后,会导致浏览器无法找到上一个session对象,会造成服务器中session死亡的假象。(非常浪费服务器性能)

 

2.8 案例的思路分析与代码步骤

验证码案例的流程分析.png

部分参考代码:

项目结构

image.png

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
function change(t) {
    t.src="http://localhost/day33/code?"+new Date().getTime();
}
</script>
</head>
<body>
    <font color="red">
        <%=
            request.getAttribute("msg")==null?"":request.getAttribute("msg")
        %>
    </font>
    <form action="http://localhost/day33/CodeYanZheng" method="get">
        验证码:<input type="text" name="code">
        <img src="http://localhost/day33/code" onclick="change(this)">
        <br>
        <input type="submit" value="开始验证">
    </form>
</body>
</html>

CodeServlet.java

这是个生成验证码的servlet,改写的代码是62-64行主要是将生成的验证码添加到session中

package com.itheima.demo04_验证码;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CodeServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 使用java图形界面技术绘制一张图片

        int charNum = 4;
        int width = 20 * 4;
        int height = 28;

        // 1. 创建一张内存图片
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        // 2.获得绘图对象
        Graphics graphics = bufferedImage.getGraphics();

        // 3、绘制背景颜色
        graphics.setColor(Color.YELLOW);
        graphics.fillRect(0, 0, width, height);

        // 4、绘制图片边框
        graphics.setColor(Color.GRAY);
        graphics.drawRect(0, 0, width - 1, height - 1);

        // 5、输出验证码内容
        graphics.setColor(Color.RED);
        graphics.setFont(new Font("宋体", Font.BOLD, 22));
        
        // 随机输出4个字符
        String s = "ABCDEFGHGKLMNPQRSTUVWXYZ23456789";
        Random random = new Random();
        
        // session中要用到
        String msg = "";
        
        int x = 5;
        for (int i = 0; i < charNum; i++) {
            int index = random.nextInt(32);
            String content = String.valueOf(s.charAt(index));
            
            msg += content;
            graphics.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
            graphics.drawString(content, x, 22);
            x += 20;
        }
        
        System.out.println("本次验证码是:"+msg);
        //将msg的值保存到session中
        request.getSession().setAttribute("seCode",msg);
        
        
        // 6、绘制干扰线
        graphics.setColor(Color.GRAY);
        for (int i = 0; i < 5; i++) {
            int x1 = random.nextInt(width);
            int x2 = random.nextInt(width);

            int y1 = random.nextInt(height);
            int y2 = random.nextInt(height);
            graphics.drawLine(x1, y1, x2, y2);
        }

        // 释放资源
        graphics.dispose();

        // 图片输出 ImageIO
        ImageIO.write(bufferedImage, "jpg", response.getOutputStream());

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

}

CodeYanZheng.java

package com.itheima.demo04_验证码;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class EqualsServlet
 */
public class CodeYanZheng extends HttpServlet {
    //专门比较验证码的servlet
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1:参  调   存    转
        String c = request.getParameter("code");//获取用户填写的验证码
        //2:获取session中的验证码
        Object sec = request.getSession().getAttribute("seCode");//根据属性名从session获取属性值
        //3:比较
        if(c!=null&&c.equalsIgnoreCase((String)sec)){
            //说明验证码对了
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().println("验证码正确,可以去购物了...");
        }else{
            //说明验证码错了
            request.setAttribute("msg","验证码错误!");
            request.getRequestDispatcher("/index.jsp").forward(request, response);
        }
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值