金九银十已到!Cookie 和 Session的这些知识你必须知道,面试必问!

前言

  1. 会话:一次会话中包含屡次请求和响应
    注:一次会话表示浏览器第一次给服务器发送请求,会话创建,直到有一方断开为止
  2. 功能:在一次会话的屡次请求间共享数据
  3. 方式:
    (1) 客户端会话技术:Cookie
    (2) 服务器端会话技术:Session

Cookie

  1. 概念:将数据保存到客户端,客户端有了Cookie以后,每次请求都会发送给服务器
  2. 使用步骤:
    (1) 建立Cookie对象,参数中绑定数据(键值对)
    new Cookie(String name, String value);
    (2) 客户端向服务器发送请求后,服务器向客户端发送Cookie对象
    response.addCookie(Cookie cookie);
    (3) 客户端收到Cookie后,再次发送请求时,服务器获取从客户端发来的Cookie对象
    Cookie[] request.getCookies();
    (4) 服务器获得Cookie对象后,使用getName与getValue方法获得Cookie对象的数据

代码演示:演示Cookie的使用步骤
(1) 此工程Tomcat的设置:
html

(2) 在src下建立CookieTest1.javajava

@WebServlet("/CookieTest1")
public class CookieTest1 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1\. 建立Cookie对象,参数相似键值对
        Cookie cookie = new Cookie("msg", "hello");
        //2\. 客户端向浏览器发送Cookie
        response.addCookie(cookie);
    }
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
    }
}

(3) 在src下建立CookieTest2.javaweb

@WebServlet("/CookieTest2")
public class CookieTest2 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //3\. 服务器获取Cookie对象
        Cookie[] cookies = request.getCookies();
        //4\. 服务器获取Cookie对象的值
        for (Cookie cookie :
                cookies) {
            String name = cookie.getName();
            String value = cookie.getValue();
            System.out.println("得到的Cookie对象的值:" + name + ":" + value);
        }
    }
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

运行结果:
在浏览器地址栏先输入:http://localhost:8080/MyTest/CookieTest1
后输入:http://localhost:8080/MyTest/CookieTest2
控制台输出:得到的Cookie对象的值:msg:hello数组

  1. 上述程序原理:基于响应头set-cookie和请求头cookie实现

Cookie的细节

1.一次能够发送多个Cookie对象,使用response调用屡次addCookie方法便可浏览器

2.Cookie在浏览器中保存的时间:
(1) 默认状况下,当浏览器关闭后,Cookie数据被销毁
(2) 持久化存储:
使用Cookie对象的setMaxAge(int seconds)方法:
a. 正数:将Cookie数据写到硬盘中存储,参数指定存活的秒数,时间到后,数据失效, 此时间指的是建立cookie后开始计时,并非关闭浏览器后才开始计时
b. 负数:默认状况
c. 零:删除cookie信息安全

3.在Tomcat 8以后Cookie能够存中文,但特殊中文字符仍不支持,建议使用URL编码格式服务器

4.Cookie的共享问题:
(1) 一个Tomcat服务器中,部署了多个web项目,这些web项目cookie的共享说明:
① 默认状况cookie没法共享
② 使用Cookie对象的setPath(String path)方法设置cookie的获取范围:
a. 默认状况,参数是web工程路径,只有这个工程才能够访问到,其他工程没法访问
b. 若是要共享,能够设置参数为”/” ( /被浏览器解析获得的地址为http://ip:port/ )
(2) 不一样的Tomcat服务器间cookie的共享说明:
使用Cookie对象的setDomain(String path)方法,参数设置为一级域名,则一级域名相同的不一样服务器之间Cookie可共享
如:setDomain(“.baidu.com”),则tieba.baidu.com与news.baidu.com等的cookie可共享cookie

Cookie的特色和做用

1.Cookie在客户端存储数据,客户端有了cookie以后,每次发送请求都会把cookie发送给服务器
2.浏览器对单个Cookie有大小限制(4KB),对同一个域名下的总cookie数量也有限制(20个)
3.做用:
(1)Cookie通常用于存储少许的安全性较低的数据
(2)在不登录的状况下,完成服务器对客户端的身份识别,如没有登陆百度帐号的前提下打开百 度,设置搜索引擎搜索时不提示,之后打开浏览器访问百度时,不会再出现搜索提示框,原 理:百度服务器将设置的Cookie信息保存到浏览器,下次访问百度时,百度服务器获取浏览 器的Cookie,根据Cookie的值决定要不要显示提示框session

Cookie案例:记录上一次访问的时间

  1. 需求:访问一个Servlet程序:
    (1) 若是是第一次访问,提示:您好,欢迎您首次访问
    (2) 若是不是第一次访问,提示:欢迎回来,您上次的访问时间是:xxxx
  2. 分析:
    使用Cookie来完成,在服务器判断客户端是否有一个名为lastTime的cookie对象
    (1) 有,不是第一次访问:
    ①在浏览器显示:欢迎回来,您上次的访问时间是:xxxx
    ②将如今的时间写回名为lastTime的cookie中
    (2) 无,是第一次访问:
    ①在浏览器显示:您好,欢迎您首次访问
    ②将如今的时间写回名为lastTime的cookie中

代码演示:使用jsp页面完成此案例app

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>CookieTest</title>
</head>
<body>
    <%-- jsp页面经过首行的page标签自动的设置响应的格式,因此向浏览器输出数据不会乱码 --%>
    <%
        //1\. 服务器获取客户端的全部cookie
        Cookie[] cookies = request.getCookies();
        //2\. 获取的cookie不必定含有lastTime,用一个布尔类型判断
        boolean flag = false;
                //3\. 遍历cookie数组,判断是否有lastTime
        if(cookies != null && cookies.length > 0) {
            for (Cookie cookie :
                    cookies) {
                String cookieName = cookie.getName();
                if ("lastTime".equals(cookieName)) {
                    // 有lastTime,不是第一次访问
                    flag = true;
                    // 将如今的时间写回lastTime的cookie中
                    Date date = new Date();
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
                    String format = sdf.format(date);
                    // 防止乱码,向cookie对象中保存的中文数据使用URL编码
                    format = URLEncoder.encode(format, "UTF-8");
                    // 向名为lastTime的cookie中保存此时间
                    cookie.setValue(format);
                    // 设置cookie的存活时间
                    cookie.setMaxAge(60 * 60 * 24 * 30); //一个月
                    // 将cookie写回客户端
                    response.addCookie(cookie);
                    // 获取此cookie的value时间值,用于写出时间到浏览器
                    String cookieValue = cookie.getValue();
                    cookieValue = URLDecoder.decode(cookieValue, "UTF-8");
                    out.write("欢迎回来,您上次的访问时间是:" + cookieValue);
                    break; //找到了须要的cookie,就不须要判断别的cookie了
                }
            }
        }
    %>
    <%
        if(cookies == null || cookies.length == 0 || flag == false) {
            // 没有lastTime,第一次访问,将当前时间保存至cookie,向客户端传递此cookie
            Date date = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
            String format = sdf.format(date);
            format = URLEncoder.encode(format, "UTF-8");
            Cookie cookie = new Cookie("lastTime", format);
            cookie.setMaxAge(60 * 60 * 24 * 30);
            response.addCookie(cookie);
            out.write("您好,欢迎您首次访问");
        }
    %>
</body>
</html>

Session的介绍

  1. 概念:Session是服务器端会话技术,在一次会话的屡次请求间共享数据,将数据保存到服务器 端,经常使用来保存用户登陆以后的信息
  2. 快速入门:
    (1) 获取HttpSession对象
    HttpSession session = request.getSession();
    注:①第一次调用表示建立Session会话
    ②以后调用都是获取前面建立好的Session会话对象
    (2) 使用HttpSession对象的方法
    void setAttribute(String name, Object value);
    Object getAttribute(String name);
    void removeAttribute(String name);

代码演示:演示Session的使用
(1) 在src下建立SessionDemo1.java

@WebServlet("/SessionDemo1")
public class SessionDemo1 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1\. 建立Session会话
        HttpSession session = request.getSession();
        //2\. 存储数据
        session.setAttribute("msg", "Hello! Session!");
    }
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

(2) 在src下建立SessionDemo2.java

@WebServlet("/SessionDemo2")
public class SessionDemo2 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1\. 获取Session
        HttpSession session = request.getSession();
        //2\. 获取数据
        Object msg = session.getAttribute("msg");
        System.out.println(msg);
    }
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

运行结果:
在浏览器地址栏先输入:http://localhost:8080/MyTest/SessionDemo1
后输入:http://localhost:8080/MyTest/SessionDemo2
控制台输出:Hello! Session!

  1. 上述程序原理:Session底层是基于Cookie来实现的

    注意:每一个Session会话都有一个惟一的id值做为标识,getId方法可获得此id值

Session的细节

  1. Session被销毁的方式
    (1)服务器关闭
    (2)Session对象调用invalidate()
    (3)Session默认失效时间:30分钟,能够到web.xml中修改配置文件修改默认失效时间

    <session-config>
         <session-timeout>30</session-timeout>
     </session-config>
  2. 客户端关闭以后服务器不关闭,两次获取的Session是否为同一个?
    (1) 默认状况下,不是,Cookie消失,其中的Session天然也消失
    (2) 若是须要相同,进行以下操做:

  1. 客户端不关闭,服务器关闭以后,两次获取的Session是否为同一个?
    不是同一个Session,可是为了保证数据的不丢失,Tomcat服务器自动完成:
    (1) Session的钝化:
    在服务器正常关闭以前,将Session对象序列化到硬盘上
    (2) Session的活化:
    在服务器启动以后,将Session文件反序列化成为内存中的Session对象
    注意:也就是说即便获取的不是同一个Session,可是Session中的数据都是相同的
  2. Session的特色
    (1) Session用于存储一次会话的屡次请求数据,存在服务器端,一次会话只有一个session对象
    (2) Session能够存储任意类型,任意大小的数据
  3. Session与Cookie的区别:
    (1) Session存储数据在服务器端,Cookie在客户端
    (2) Session没有数据大小的限制,Cookie有(4KB)
    (3) Session数据安全,Cookie相对不安全

Cookie案例:免用户名登陆

说明:成功登陆以后,重启浏览器,再次登陆时,浏览器记住了上次登陆的用户名

代码演示:免用户名登陆的使用
(1) 建立login.jsp

<body>
    <form action="http://localhost:8080/MyTest/LoginServlet" method="post">
        用户名:<input type="text" name="username" value="${cookie.username.value}"> <br>
        密码:<input type="password" name="password"> <br>
        <input type="submit" value="登陆">
    </form>
</body>

(2) 建立LoginServlet.java

public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        //设置正确的用户名为周杰伦,密码是123
        if ("jay".equals(username) && "123".equals(password)) {
            Cookie cookie = new Cookie("username", username);
            cookie.setMaxAge(60 * 60 * 24 * 7); //cookie保存一周
            response.addCookie(cookie);
            System.out.println("登录成功!");
        } else {
            System.out.println("登录失败!");
        }
    }
}

运行结果:
使用正确的用户名和密码以后,再次访问登录页面,用户名输入框会自动的填入jay

谷歌浏览器查看Cookie

验证码的底层原理

谷歌图片验证码的使用

谷歌验证码的使用步骤:

  1. 导入谷歌验证码的jar包:
  2. 在web.xml中进行以下的配置(写成同样的便可):
<servlet>
    <servlet-name>KaptchaServlet</servlet-name>
    <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>KaptchaServlet</servlet-name>
    <url-pattern>/kaptcha.jpg</url-pattern>
</servlet-mapping>
注:表明访问这个Servlet就会生成验证码及图片,并将此验证码保存到Session域中,每次访问都会生成不一样的验证码
  1. 在表单中使用img标签显示验证码
<body>
    <form action="http://localhost:8080/MyTest/Servlet">
        验证码:<input type="text" style="width: 80px;" name="code">
        <img src="http://localhost:8080/MyTest/kaptcha.jpg" alt="验证码没有找到"
             style="width: 100px; height: 28px;" id="code_img"> <br>
        <input type="submit" value="登陆">
    </form>
</body>
  1. 在服务器处理获取的验证码
public class Servlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取Session中的验证码
        String attribute = (String) request.getSession().getAttribute(KAPTCHA_SESSION_KEY);
        //删除Session中的验证码
        request.getSession().removeAttribute(KAPTCHA_SESSION_KEY);
        //获取用户输入的验证码
        String code = request.getParameter("code");
        if (attribute.equalsIgnoreCase(code)) {
            System.out.println("验证码正确!");
        } else {
            System.out.println("验证码错误!");
        }
    }
}

运行结果:

点击图片切换验证码

代码演示:为上述验证码绑定单击事件(使用script标签)

window.onload = function () {
    //经过验证码图片的id属性值绑定单击事件
    var elementById = document.getElementById("code_img");
    elementById.onclick = function () {
        //1\. 事件响应的function函数中的this对象是当前正在响应事件的标签的dom对象
        //2\. src属性可读可写
        this.src = "http://localhost:8080/MyTest/kaptcha.jpg?d=" + new Date();
    }
}

运行结果:每次点击验证码的图片都会变成新的验证码,并将新验证码保存到session域中

最后

感谢你看到这里,看完有什么的不懂的能够在评论区问我,以为文章对你有帮助的话记得给我点个赞,天天都会分享java相关技术文章或行业资讯,欢迎你们关注和转发文章!