前言

  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的设置:

(2) 在src下创建CookieTest1.java

@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.java

@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的特点和作用

1.Cookie在客户端存储数据,客户端有了cookie之后,每次发送请求都会把cookie发送给服务器

2.浏览器对单个Cookie有大小限制(4KB),对同一个域名下的总cookie数量也有限制(20个)

3.作用:

(1)Cookie一般用于存储少量的安全性较低的数据

(2)在不登陆的情况下,完成服务器对客户端的身份识别,如没有登录百度账号的前提下打开百 度,设置搜索引擎搜索时不提示,以后打开浏览器访问百度时,不会再出现搜索提示框,原 理:百度服务器将设置的Cookie信息保存到浏览器,下次访问百度时,百度服务器获取浏览 器的Cookie,根据Cookie的值决定要不要显示提示框

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

  1. 需求:访问一个Servlet程序:

    (1) 如果是第一次访问,提示:您好,欢迎您首次访问

    (2) 如果不是第一次访问,提示:欢迎回来,您上次的访问时间是:xxxx
  2. 分析:

    使用Cookie来完成,在服务器判断客户端是否有一个名为lastTime的cookie对象

    (1) 有,不是第一次访问:

    ①在浏览器显示:欢迎回来,您上次的访问时间是:xxxx

    ②将现在的时间写回名为lastTime的cookie中

    (2) 无,是第一次访问:

    ①在浏览器显示:您好,欢迎您首次访问

    ②将现在的时间写回名为lastTime的cookie中

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

<%@ 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) 如果需要相同,进行如下操作:

  3. 客户端不关闭,服务器关闭之后,两次获取的Session是否为同一个?

    不是同一个Session,但是为了保证数据的不丢失,Tomcat服务器自动完成:

    (1) Session的钝化:

    在服务器正常关闭之前,将Session对象序列化到硬盘上

    (2) Session的活化:

    在服务器启动之后,将Session文件反序列化成为内存中的Session对象

    注意:也就是说即使获取的不是同一个Session,但是Session中的数据都是相同的

  4. Session的特点

    (1) Session用于存储一次会话的多次请求数据,存在服务器端,一次会话只有一个session对象

    (2) Session可以存储任意类型,任意大小的数据

  5. 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相关技术文章或行业资讯,欢迎大家关注和转发文章!

金九银十已到!Cookie 和 Session的这些知识你必须知道,面试必问!的更多相关文章

  1. “金九银十”已过,总结我的天猫、蚂蚁、头条面试经历(Java岗)

    跳槽时时刻刻都在发生,但是我建议大家跳槽之前,先想清楚为什么要跳槽.切不可跟风,看到同事一个个都走了,自己也盲目的开始面试起来(期间也没有准备充分),到底是因为技术原因(影响自己的发展,偏移自己规划的 ...

  2. 金九银十已到!掌握这300道java高频面试题,助你面试BAT无忧!

    前言 不知不觉已经到了九月了,回首看年初的时候简直像做梦一样.不得不说时间真的是无情一般的流逝,题外话就不多说了!回归正题,现在已经到了今年最后一波大好的跳槽涨薪的时机了,错过了这一次可能你就得等到明 ...

  3. 备战金九银十,Java研发面试题(Spring、MySQL、JVM、Mybatis、Redis、Tomcat)[带答案],刷起来!

    八月在即,马上就是"金九银十",又是跳槽招聘季.咱们这行公认涨薪不如跳槽加的快.但不建议频繁跳槽,还是要学会融合团队,抓住每个机会提升技能. 苏先生在这里给大家整理了一套各大互联网 ...

  4. 不等"金九银十",金风八月,我早已拿下字节跳动的offer

    字节跳动,我是在网上投的简历,之前也投过一次,简历都没通过删选,后来让师姐帮我改了一下简历,重新投另一个部门,获得了面试机会.7月23日,中午HR打电话过来预约了下午4点半面试,说会在线写代码,让我准 ...

  5. 金九银十想去跳槽面试?那这份Java面经你真得看看了,写的非常详细!

    前言 前两天在和朋友吃饭的时候聊到时间这个东西是真的过的好坏啊,金三银四仿佛还在昨天.一眨眼金九银十又快到了,对程序员来说这两个是一年最合适的跳槽涨薪环节了,今年的你已经做好准备了吗?不妨看看这篇文章 ...

  6. 金九银十跳槽高峰,面试必备之 Redis + MongoDB 常问80道面试题

    前言 有着“金九银十”之称的招聘旺季已经开启,跳槽高峰期也如约而至. 本文为主要是 Redis + MongoDB 知识点的攻略,希望能帮助到大家. 内容较多,大家准备好耐心和瓜子矿泉水. Redis ...

  7. Java程序员备战“金九银十”必备的面试技巧(附携程Java岗面试题)

    一.面试前的准备 1.1 如何准备一场面试1.1.1 如何获取大厂面试机会1.1.2 面试必知 ①. 准备介绍自己 ②. 关于着装 ③ .随身带上自己的成绩单和简历 ④. 如果笔试就提前刷一些笔试题 ...

  8. Android&Java面试题大全—金九银十面试必备

    声明本文由作者:Man不经心授权转载,转载请联系原文作者原文链接:https://www.jianshu.com/p/375ad14096b3, 类加载过程 Java 中类加载分为 3 个步骤:加载. ...

  9. 想要金九银十面试通关,不懂 Java多线程肯定是不行的!

    作者 | 纳达丶无忌 如果对什么是线程.什么是进程仍存有疑惑,请先 Google 之,因为这两个概念不在本文的范围之内. 用多线程只有一个目的,那就是更好的利用 CPU 的资源,因为所有的多线程代码都 ...

随机推荐

  1. MySQL安装版本介绍

    MySQL安装 源码安装 二进制格式的程序包 程序包管理器安装 yum dnf MySQL在CentOS上的情况 6上只有mySQL 7上只有mariadb 8上既有mysql也有mariadb Ce ...

  2. vue学习大纲

    第一单元  vue基础 第二单元  VueU学习

  3. 由反转链表想到python链式交换变量

    这两天在刷题,看到链表的反转,在翻解体思路时看到有位同学写出循环中一句搞定三个变量的交换时觉得挺6的,一般用的时候都是两个变量交换(a,b=b,a),这种三个变量的交换还真不敢随便用,而且这三个变量都 ...

  4. pyqt5为控件设置提示信息

    # 显示控件提示消息 import sys from PyQt5.QtWidgets import QHBoxLayout,QMainWindow,QApplication,QToolTip,QPus ...

  5. webpack学习遇到大坑(纯属自己记录)

    分清webpack1与webpack2区别 1.webpack2的loader不能使用简写了,否则会报如下的错 正确如下: 2.node-sass安装失败,无法下载:Cannot download h ...

  6. D. Equalize the Remainders 解析(思維)

    Codeforce 999 D. Equalize the Remainders 解析(思維) 今天我們來看看CF999D 題目連結 題目 略,請直接看原題 前言 感覺要搞個類似\(stack\)的東 ...

  7. C语言知识点复习梳理

    C语言知识点复习梳理 C语言的知识点讲完了,接下来就是做一下整理与总结,然后就会进入其他知识的学习. 本文目录如下: 基础知识. 顺序程序设计. 数据类型. 标准输入输出. 进制转换. 选择结构. 循 ...

  8. 2020年Android开发最新整理阿里巴巴、字节跳动、小米面经,你不看看吗?

    前言 2020年是转折的一年,上半年疫情原因,很多学android开发的小伙伴失业了,虽找到了一份工作,但高不成低不就,下半年金九银十有想法更换一份工作,很多需要大厂面试经验和大厂面试真题的小伙伴,想 ...

  9. Java中的(String args[])

    1. DOS下运行 首先,String args[] 这个形式可以直接看出它就是一个字符串数组充当main函数形式参数,args是arguments的缩写,不是关键字(就是一个数组名),可以改但没必要 ...

  10. JS对象创建的几种方式整理

    ​ 本文主要介绍了JS对象创建的几种方式 第一种:Object构造函数创建 var Person = new Object(); Person.name = 'Nike'; Person.age = ...