前言

  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

  1. @WebServlet("/CookieTest1")
  2. public class CookieTest1 extends HttpServlet {
  3. @Override
  4. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  5. //1\. 创建Cookie对象,参数类似键值对
  6. Cookie cookie = new Cookie("msg", "hello");
  7. //2\. 客户端向浏览器发送Cookie
  8. response.addCookie(cookie);
  9. }
  10. @Override
  11. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  12. this.doPost(request,response);
  13. }
  14. }

(3) 在src下创建CookieTest2.java

  1. @WebServlet("/CookieTest2")
  2. public class CookieTest2 extends HttpServlet {
  3. @Override
  4. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  5. //3\. 服务器获取Cookie对象
  6. Cookie[] cookies = request.getCookies();
  7. //4\. 服务器获取Cookie对象的值
  8. for (Cookie cookie :
  9. cookies) {
  10. String name = cookie.getName();
  11. String value = cookie.getValue();
  12. System.out.println("获得的Cookie对象的值:" + name + ":" + value);
  13. }
  14. }
  15. @Override
  16. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  17. this.doPost(request, response);
  18. }
  19. }

运行结果:

在浏览器地址栏先输入: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页面完成此案例

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>CookieTest</title>
  5. </head>
  6. <body>
  7. <%-- jsp页面通过首行的page标签自动的设置响应的格式,所以向浏览器输出数据不会乱码 --%>
  8. <%
  9. //1\. 服务器获取客户端的所有cookie
  10. Cookie[] cookies = request.getCookies();
  11. //2\. 获取的cookie不一定含有lastTime,用一个布尔类型判断
  12. boolean flag = false;
  13. //3\. 遍历cookie数组,判断是否有lastTime
  14. if(cookies != null && cookies.length > 0) {
  15. for (Cookie cookie :
  16. cookies) {
  17. String cookieName = cookie.getName();
  18. if ("lastTime".equals(cookieName)) {
  19. // 有lastTime,不是第一次访问
  20. flag = true;
  21. // 将现在的时间写回lastTime的cookie中
  22. Date date = new Date();
  23. SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
  24. String format = sdf.format(date);
  25. // 防止乱码,向cookie对象中保存的中文数据使用URL编码
  26. format = URLEncoder.encode(format, "UTF-8");
  27. // 向名为lastTime的cookie中保存此时间
  28. cookie.setValue(format);
  29. // 设置cookie的存活时间
  30. cookie.setMaxAge(60 * 60 * 24 * 30); //一个月
  31. // 将cookie写回客户端
  32. response.addCookie(cookie);
  33. // 获取此cookie的value时间值,用于写出时间到浏览器
  34. String cookieValue = cookie.getValue();
  35. cookieValue = URLDecoder.decode(cookieValue, "UTF-8");
  36. out.write("欢迎回来,您上次的访问时间是:" + cookieValue);
  37. break; //找到了需要的cookie,就不需要判断别的cookie了
  38. }
  39. }
  40. }
  41. %>
  42. <%
  43. if(cookies == null || cookies.length == 0 || flag == false) {
  44. // 没有lastTime,第一次访问,将当前时间保存至cookie,向客户端传递此cookie
  45. Date date = new Date();
  46. SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
  47. String format = sdf.format(date);
  48. format = URLEncoder.encode(format, "UTF-8");
  49. Cookie cookie = new Cookie("lastTime", format);
  50. cookie.setMaxAge(60 * 60 * 24 * 30);
  51. response.addCookie(cookie);
  52. out.write("您好,欢迎您首次访问");
  53. }
  54. %>
  55. </body>
  56. </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

  1. @WebServlet("/SessionDemo1")
  2. public class SessionDemo1 extends HttpServlet {
  3. @Override
  4. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  5. //1\. 创建Session会话
  6. HttpSession session = request.getSession();
  7. //2\. 存储数据
  8. session.setAttribute("msg", "Hello! Session!");
  9. }
  10. @Override
  11. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  12. this.doPost(request, response);
  13. }
  14. }

(2) 在src下创建SessionDemo2.java

  1. @WebServlet("/SessionDemo2")
  2. public class SessionDemo2 extends HttpServlet {
  3. @Override
  4. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  5. //1\. 获取Session
  6. HttpSession session = request.getSession();
  7. //2\. 获取数据
  8. Object msg = session.getAttribute("msg");
  9. System.out.println(msg);
  10. }
  11. @Override
  12. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  13. this.doPost(request, response);
  14. }
  15. }

运行结果:

在浏览器地址栏先输入: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中修改配置文件修改默认失效时间

    1. <session-config>
    2. <session-timeout>30</session-timeout>
    3. </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

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

(2) 创建LoginServlet.java

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

运行结果:

使用正确的用户名和密码之后,再次访问登陆页面,用户名输入框会自动的填入jay

谷歌浏览器查看Cookie

验证码的底层原理

谷歌图片验证码的使用

谷歌验证码的使用步骤:

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

运行结果:

点击图片切换验证码

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

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

运行结果:每次点击验证码的图片都会变成新的验证码,并将新验证码保存到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. CentOS8 yum安装Mariadb10.4

    CentOS8 yum安装Mariadb10.4 https://downloads.mariadb.org/mariadb/repositories/#distro=CentOS&distr ...

  2. springboot添加拦截器

    一,编写拦截器 public class TokenInterceptor implements HandlerInterceptor { @Override public boolean preHa ...

  3. python中,*args和**kwargs这两个参数的作用是什么?

    *args和**kwargs这两个都是不定长参数,可以解决函数中参数不固定的问题,*args可以把位置参数转化成元组,**kwagrs可以把关键字参数转化成字段

  4. HP UNIX 查看 修改IP地址

    # 查看所有IP地址h01_root[/]# lanscan Hardware Station Crd Hdw Net-Interface NM MAC HP-DLPI DLPI Path Addre ...

  5. k8s部署之系统初始化(一)

    初始化 1.安装依赖包 yum -y install tree lrzsz nmap nc telnet vim wget lsof network-tools bash-completion bas ...

  6. Redis常用命令(5)——Set

    SADD 格式:SADD key member [member ...] 作用:在集合key中插入一个或多个元素.如果member已经存在,则忽略member.如果key不存在则先创建集合key. 返 ...

  7. 同时使用mybatis和mybatis-plus时,pageHelper失效问题解决

    一.问题由来 最近刚拿到一个别人的项目,该项目中使用mybatis和mybatis-plus来操作数据库,我们需要在此基础上添加新功能. 做功能开发时一切都很顺利,我也很快完成了自己负责的模块,然后和 ...

  8. python数据类型之set(集合)

    set集合 关注公众号"轻松学编程"了解更多. 1.概述 set与dict类似,但set是一组key的集合,与dict的区别在于set不存储value. 本质:无序且无重复元素的集 ...

  9. 一路踩坑,被迫聊聊 C# 代码调试技巧和远程调试

    一:背景 1. 讲故事 每次项目预交付的时候,总会遇到各种奇葩的坑,我觉得有必要梳理一下以及如何快速解决的,让后来人避避坑,这篇就聊聊自己的所闻所遇: 我去,本地环境代码跑的哧溜,上了测试环境出问题 ...

  10. MySQL全面瓦解7:查询的过滤条件

    概述 在实际的业务场景应用中,我们经常要根据业务条件获取并筛选出我们的目标数据.这个过程我们称之为数据查询的过滤.而过滤过程使用的各种条件(比如日期时间.用户.状态)是我们获取精准数据的必要步骤, 这 ...