目录

Servlet学习笔记(四)

一、会话技术Cookie、session

1. 什么是会话技术?

指用户打开一个浏览器,访问一个网站,只要不关闭该浏览器,不管该用户点击多少个超链接,访问多少资源,直到用户关闭浏览器,整个这个过程我们称为一次会话,在一次会话中可以有多次请求,可以共享数据

会话跟踪技术有Cookie和Session,Cookie技术是先出现的

2. 会话技术有什么用?

我们在登录网站时候,有的会提示是否自动登录,这样得到下次访问就可以直接不用登录了,这就是使用了会话技术的

3. Cookie

3.1 什么是Cookie?

Cookie是由W3C组织提出,最早由netscape社区发展的一种机制

  • 我也之间交互是通过HTTP协议传输数据的,但是HTTP协议是无状态的,一旦提交完数据,浏览器和服务器的连接就会被关闭,再次连接时候又是一个新的连接,服务器无法直到是否浏览器上次来过了。多以W3C提出了:给每一个用户发一个通行证,无论谁访问都携带通行证,这样服务器就可以直到用户的信息了
3.2 使用Cookie

Cookie是基于响应头set-cookie请求头cookie实现的

**浏览器对于单个cookie 的大小有限制(4kb) **

添加Cookie

//设置response的编码
response.setContentType("text/html;charset=utf-8");
//创建一个Cookie对象
Cookie cookie = new Cookie("username", "linzeliang");
//将cookie的maxAge过期时间设置为1小时
cookie.setMaxAge(60 * 60)
//将cookie对象添加到response对象,发送cookie
response.addCookie(cookie);

获取Cookie

//通过request获取浏览器发送来的Cookie
Cookie[] cookies = request.getCookies();
//遍历cookies,获取每一个cookie
for (Cookie cookie : cookies) {
System.out.println(cookie.getValue());
}

Cookie工作流程:

  • 浏览器访问服务器,如果服务器需要记录该用户的状态,就使用response向浏览器发送一个Cookie,浏览器会把Cookie保存起来。当浏览器再次访问服务器的时候,浏览器会把请求的网址连同Cookie一同交给服务器

Cookie API:

  • Cookie类用于创建一个Cookie对象
  • response接口中定义了一个addCookie方法,它用于在其响应头中增加一个相应的Set-Cookie头字段
  • request接口中定义了一个getCookies方法,它用于获取客户端提交的Cookie

常用的Cookie方法:

  • public Cookie(String name,String value)
  • setValue与getValue方法
  • setMaxAge与getMaxAge方法
  • setPath与getPath方法
  • setDomain与getDomain方法
  • getName方法
3.2 可以创建多个Cookie吗?

可以的。可以同通过调用多次addCookie方法来发送多个cookie,浏览器就也会收到多个Cookie

3.3 Cookie在浏览器保存多久时间?
  • 在默认情况下,只要关闭浏览器,Cookie就会被销毁
  • 如果要持久化储存,即存储到硬盘上,则需要在服务器设置response.setMaxAge(int seconds)
    • 如果seconds为整数,则数字就是代表存储多少秒
    • 如果为负数(也就是默认的-1),代表Cookie是临时性的,关闭浏览器立即销毁该Cookie
    • 如果为0,代表删除Cookie信息,即下一次浏览器向客户端请求时,不带该cookie,因为已经删除了
3.4 Cookie保存中文
  • 在Tomcat8之前,Cookie不能保存中文,需要将中文进行URL编码

    Cookie cookie = new Cookie("username", URLEncoder.encode("名字", "UTF-8"));
    //同样,既让是通过URL编码发送到了浏览器,浏览器也是按照URL编码存储到硬盘中的,我们在获取cookie时候还需要将其解码
    Cookie[] cookies = request.getCookies();
    for (Cookie cookie : cookies) {
    String name = cookie.getValue();
    //URLDecoder解码
    String value = URLDecoder.decode(name, "UTF-8");
    System.out.println(value);
    }
  • 在Tomcat8及其之后,cookie支持中文数据,但是还是不支持特殊字符。为了容易维护,建议都使用URL编码进行存储和解析

3.5 Cookie的不可跨域名性

在访问Servlet的时候浏览器是不是把所有的Cookie都带过去给服务器会不会修改了别的网站的Cookie?是不会的的,Cookie具有不可跨域名性。浏览器判断一个网站是否能操作另一个网站的Cookie的依据是域名。所以一般来说,当我访问baidu的时候,浏览器只会把baidu颁发的Cookie带过去,而不会带上google的Cookie

3.6 修改、删除Cookie的值

Cookie机制也没有提供修改Cookie的方法,那么我们怎么修改Cookie的值呢?

我们可以通过Cookie的名字相同。通过response来添加到浏览器中,这样就会覆盖之前的Cookie了

Cookie删除即将色图Max Age修改为0即可

注意:删除,修改Cookie时,新建的Cookie除了value、maxAge之外的所有属性都要与原Cookie相同。否则浏览器将视为不同的Cookie,不予覆盖,导致删除修改失败

3.7 Cookie的共享

正常的cookie只能在一个应用中共享,即一个cookie只能由创建它的应用获得。

  1. 默认情况下在一个tomcat服务器中,部署了多个web项目,那么在这些web项目中cookie不能共享,如果需要共享,只需要设置setPath("/")即可,因为默认的就是当前的虚拟目录("/"指的是相对路径,本例中即是应用部署路径,tomcat/webapp)

    设置cookie.setPath("/webapp_a/jsp")或者cookie.setPath("/webapp_a/jsp/")的时候,只有在webapp_a/jsp下面可以获得cookie,在webapp_a下面但是在jsp文件夹外的都不能获得cookie

  2. 不同的tomcat服务器间cookie共享问题

    Cookie的domain属性决定运行访问Cookie的域名。domain的值规定为“.域名”

    • Cookie的隐私安全机制决定Cookie是不可跨域名的。也就是说www.baidu.comwww.google.com之间的Cookie是互不交接的。即使是同一级域名,不同二级域名也不能交接,也就是说:www.goole.comwww.image.goole.com的Cookie也不能访问

    • 如果现在我希望一级域名相同的网页Cookie之间可以相互访问。也就是说www.img.linzeliang.com可以获取到www.linzeliang.com的Cookie就需要使用到domain方法

      Cookie cookie = new Cookie("username", "linzeliang");
      cookie.setMaxAge(60 * 60);
      cookie.setDomain(".linzeliang.com");
      response.addCookie(cookie);
  3. setPath()和setDomain()区别:

    • Cookie中的setDomain()主要用来在两个不同名称但是后缀相同的网站地址上(不同主机),这样两个网站就能使用同一个cookie了
    • setPath()主要用来确定什么后缀下能够使用这个cookie,即地址栏上面的地址的约束
3.8 Cookie的安全属性

HTTP协议不仅是无状态,而且也不安全的,因为是明文传输的,如果不希望Cookie在非安全协议中传输,那么可以设置Cookie的secure属性为true,这样浏览器只会在HTTPS和SSL等安全协议中传输该Cookie

3.9 Cookie的应用

显示用户的上次访问时间

  • 如果用户第一次登录,那么就记录下时间,发送Cookie,并且在页面打印时第一次登录;如果不是第一次,就显示上一次是什么时候登录的

  • 代码如下:

    response.setContentType("text/html;charset=utf-8");
    //获取浏览器发送的所以cookie
    Cookie[] cookies = request.getCookies();
    //用来判断是否访问过了
    boolean flag = false;
    if (cookies != null && cookies.length != 0) {
    for (Cookie cookie : cookies) {
    if ("lastTime".equals(cookie.getName())) {
    //标记访问过了
    flag = true;
    //获取上一次登录记录
    String dateValue = cookie.getValue();
    dateValue = URLDecoder.decode(dateValue, "utf-8");
    PrintWriter pw = response.getWriter();
    //显示到浏览器中
    pw.write("<center><h1>您好,您上一次登录是在" + dateValue + "</h1></center>"); //获取这次访问的时间记录
    Date date = new Date();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
    String str_date = sdf.format(date);
    str_date = URLEncoder.encode(str_date, "utf-8");
    cookie.setValue(str_date);
    cookie.setMaxAge(60*60*24*30);
    //发送新的Cookie,覆盖掉原来的
    response.addCookie(cookie); break;
    }
    }
    }
    //第一次访问
    if (cookies == null || cookies.length == 0 || flag == false) {
    Date date = new Date();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
    String str_date = sdf.format(date);
    //要用URL编码,否则空格浏览器不能解析
    str_date = URLEncoder.encode(str_date, "utf-8");
    Cookie cookie = new Cookie("lastTime", str_date);
    cookie.setMaxAge(60*60*24*30);
    response.addCookie(cookie);
    }

4.Session

4.1什么是Session?

Session 服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中,对应的是HttpSession对象

Session 是另一种记录浏览器状态的机制。不同的是Cookie保存在浏览器中,Session保存在服务器中。用户使用浏览器访问服务器的时候,服务器把用户的信息以某种的形式记录在服务器,这就是Session

如果说Cookie是检查用户身上的”通行证“来确认用户的身份,那么Session就是通过检查服务器上的”客户明细表“来确认用户的身份的。Session相当于在服务器中建立了一份“客户明细表”

有了Cookie为什么还要session?

Session比Cookie使用方便,Session可以解决Cookie解决不了的事情(Session可以存储对象,Cookie只能存储字符串)

4.2 使用Session

获取Session对象

//获取session对象
HttpSession session = request.getSession();
//设置session属性
session.setAttribute("username", "linzeliang");

从其他的Servlet访问Session对象设置的属性

HttpSession session = request.getSession();
String value = (String) session.getAttribute("username");
System.out.println(value);
//打印的结果就是linzeliang

一般来讲,当我们要存进的是用户级别的数据就用Session,那什么是用户级别呢?只要浏览器不关闭,希望数据还在,就使用Session来保存

Session API

  • long getCreationTime();【获取Session被创建时间】
  • String getId();【获取Session的id】
  • long getLastAccessedTime();【返回Session最后活跃的时间】
  • ServletContext getServletContext();【获取ServletContext对象】
  • void setMaxInactiveInterval(int var1);【设置Session超时时间】
  • int getMaxInactiveInterval();【获取Session超时时间】
  • Object getAttribute(String var1);【获取Session属性
  • Enumeration getAttributeNames();【获取Session所有的属性名】
  • void setAttribute(String var1, Object var2);【设置Session属性】
  • void removeAttribute(String var1);【移除Session属性】
  • void invalidate();【销毁该Session】
  • boolean isNew();【该Session是否为新的】
4.3 当客户端关闭后,服务器不关闭,两次获取session是否为同一个?
  • 默认情况下不是(虽然也会自动发送JSESSIONID,但是setMaxAge是默认的,一关闭浏览器Cookie就没了,所以无法通过ID找到原来的session,所以不相同)

  • 如果需要相同,那么可以创建Cookie,键为JSESSIONID。设置setMaxAge

    Cookie c = new Cookie("JSESSIONID", session.getId());
    c.setMaxAge(60 * 60);
    response.addCookie(c);
4.4 客户端不关闭,服务器关闭后,两次获取的session是同一个吗?
  • 不是同一个,但是为了保证数据不丢失,tomcat会自动完成如下操作:

    • session的钝化:

      • 在服务器正常关闭以前,将session对象序列化到硬盘上
    • session的活化:
      • 服务器启动后,将session文件转化为session对象(虽然对象不是同一个,但是数据确是一样的)
4.3 session什么时候被销毁?
  1. 服务器被关闭

  2. session对象调用invalidate()方法,让session中的多有属性失效,常常用于安全退出

  3. 或者等待30分钟没有活跃就会被销毁(用于用户多,防止内存溢出),但是30分钟我们可以在web.xml配置文件中修改(默认是30分钟,如果tomcat的web.xml和自己的web应用的web.xml冲突,那么以自己的为准)

    <session-config>
    <session-timeout>60(自定义时间,默认30)</session-timeout>
    </session-config>
  4. 通过setMaxInactiveInterval()方法设置

    //设置Session最长超时时间为60秒,这里的单位是秒
    session.setMaxInactiveInterval(60);
    System.out.println(session.getMaxInactiveInterval());
4.4 Session和Cookie的有效期不同
  1. session:

    • session的周期是指多长时间内没有访问
    • 如果希望session的某个属性失效,可以使用removeAttribute()方法
  2. Cookie:
    • Cookie的周期就是 从这个Cookie到达用户内存中开始计时,不管期间有没有访问过
4.5 Cookie被禁用怎么办?

由于Session是基于Cookie运行的,如果禁用了Cookie,session要怎么办呢?

  • 我们可以对URL进行重写,HttpServletResponse又encodeURL(String url)和encodeRedirectURL(String url)tring url)和encodeRedirectURL(String url),重写完成后,使用sendRedirect来重定向,这样JSESSIONID在URL中被带过去了
  • URL地址重写的原理将Session的id信息重写到URL地址中服务器解析重写后URL,获取Session的id。这样一来,即使浏览器禁用掉了Cookie,但Session的id通过服务器端传递,还是可以使用Session来记录用户的状态

encodeURL(java.lang.String url)该方法的实现机制为:

  • 先判断当前的 Web 组件是否启用 Session,如果没有启用 Session,直接返回参数 url。
  • 再判断客户端浏览器是否支持 Cookie,如果支持 Cookie,直接返回参数 url;如果不支持 Cookie,就在参数 url 中加入 Session ID 信息,然后返回修改后的 url。
4.5 Session禁用Cookie(让Session不依赖Cookie)

Java Web规范支持通过配置禁用Cookie,禁用自己项目的Cookie,在META-INF文件夹下的context.xml文件中修改(没有则创建)

如果要禁用全部web应用的Cookie,在conf/context.xml

注意该配置只是让服务器不能自动维护名为jsessionid的Cookie,并不能阻止Cookie的读写

4.8 Session的特点
  • session用于存储一次会话的多次请求的数据,存储在服务器端
  • session可以存储任意数据类型,任意大小的数据
4.9 Session和Cookie的区别

从存储方式上比较

  • Cookie只能存储字符串,如果要存储非ASCII字符串还要对其编码

  • session大小没有限制,cookie最大为4kb(4095-4097B,不同浏览器不一样,所以一般认为最大不超过4095B)

  • session存储数据安全,cookie存储数据相对来说不安全

  • Session可以存储任何类型的数据,可以把Session看成是一个容器

从隐私安全上比较

  • Cookie存储在浏览器中,对客户端是可见的。信息容易泄露出去。如果使用Cookie,最好将Cookie加密
  • Session存储在服务器上,对客户端是透明的。不存在敏感信息泄露问题。

从有效期上比较

  • Cookie保存在硬盘中,只需要设置maxAge属性为比较大的正整数,即使关闭浏览器,Cookie还是存在的
  • Session的保存在服务器中,设置maxInactiveInterval属性值来确定Session的有效期。并且Session依赖于名为JSESSIONID的Cookie,该Cookie默认的maxAge属性为-1。如果关闭了浏览器,该Session虽然没有从服务器中消亡,但也就失效了。

从对服务器的负担比较

  • Session是保存在服务器的,每个用户都会产生一个Session,如果是并发访问的用户非常多,是不能使用Session的,Session会消耗大量的内存。
  • Cookie是保存在客户端的。不占用服务器的资源。像baidu、Sina这样的大型网站,一般都是使用Cookie来进行会话跟踪。

从浏览器的支持上比较

  • 如果浏览器禁用了Cookie,那么Cookie是无用的了
  • 如果浏览器禁用了Cookie,Session可以通过URL地址重写来进行会话跟踪。

从跨域名上比较

  • Cookie可以设置domain属性来实现跨域名
  • Session只在当前的域名内有效,不可夸域名

Servlet学习笔记(四)的更多相关文章

  1. servlet学习笔记四

    Servlet 主要内容: 1)servlet初始化参数与上下文参数 2)过滤器 3)监听器一.servlet初始化参数与上下文参数 1)servlet初始化参数 把某些变量放在web.xml配置,到 ...

  2. C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻

    前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...

  3. IOS学习笔记(四)之UITextField和UITextView控件学习

    IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...

  4. java之jvm学习笔记四(安全管理器)

    java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...

  5. Learning ROS for Robotics Programming Second Edition学习笔记(四) indigo devices

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  6. Typescript 学习笔记四:回忆ES5 中的类

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  7. ES6学习笔记<四> default、rest、Multi-line Strings

    default 参数默认值 在实际开发 有时需要给一些参数默认值. 在ES6之前一般都这么处理参数默认值 function add(val_1,val_2){ val_1 = val_1 || 10; ...

  8. muduo网络库学习笔记(四) 通过eventfd实现的事件通知机制

    目录 muduo网络库学习笔记(四) 通过eventfd实现的事件通知机制 eventfd的使用 eventfd系统函数 使用示例 EventLoop对eventfd的封装 工作时序 runInLoo ...

  9. python3.4学习笔记(四) 3.x和2.x的区别,持续更新

    python3.4学习笔记(四) 3.x和2.x的区别 在2.x中:print html,3.x中必须改成:print(html) import urllib2ImportError: No modu ...

随机推荐

  1. 使用Maven那么久了,你对企业级Maven的核心配置了解多少?

    写在前面 相信从事Java工作的小伙伴们多多少少都会接触到Maven.使用Maven来搭建项目,能够极大的方便我们构建项目的依赖关系,对于项目中需要依赖的Jar包,也只是简单的在pom.xml中进行配 ...

  2. # 095 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 03 封装总结 01 封装知识点总结

    095 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 03 # 088 01 Android 零基础入门 02 Java面向对象 02 Java封装 ...

  3. 全方位剖析 Linux 操作系统,太全了!!!

    Linux 简介 UNIX 是一个交互式系统,用于同时处理多进程和多用户同时在线.为什么要说 UNIX,那是因为 Linux 是由 UNIX 发展而来的,UNIX 是由程序员设计,它的主要服务对象也是 ...

  4. Vue 网站首页加载优化

    Vue 网站首页加载优化 本篇主要讲解 Vue项目打包后 vendor.js 文件很大 如何对它进行优化 以及开启Vue的压缩 和 nginx gzip 压缩的使用, 其他就是对接口优化等  1. v ...

  5. Axure实现vcg官网首页原型图

    W240第二天第三天 Axure的简单使用: 作业实现:vcg官网首页原型图 帮助文档基础篇:原型图基础之axure线框图设计 导航栏设计: 添加通用母版header 导航栏设计注意: 鼠标移动到下面 ...

  6. 最新最最最简单的Snagit傻瓜式破解教程(带下载地址)

    最新最最最简单的Snagit傻瓜式破解教程(带下载地址) 下载地址 直接滑至文章底部下载 软件介绍 一个非常著名的优秀屏幕.文本和视频捕获.编辑与转换软件.可以捕获Windows屏幕.DOS屏幕:RM ...

  7. org.apache.ibatis.ognl.OgnlException: source is null for getProperty(null, "enterpCd")-Mybatis报错

    一.问题由来 下午快要下班时,登录测试服务器查看日志信息,看看有没有新的异常信息,如果有的话好及时修改.结果一看果然有新的异常信息. 主要的异常信息如下: 2020-10-13 14:51:03,03 ...

  8. 网站搭建-云服务器ECS的使用

    1. 查看购买的云服务器实例,重置密码 2. 查找IP进行查看,此时网页时不存在的,开始配置: 3. 登录putty或其他终端,进行网页搭建,先按教程走一遍,然后再做个性化处理: #安装Apache ...

  9. Anaconda安装和使用 akshare获取股票数据

    介绍 Anaconda是开源的Python包管理器.既是Python各种库的大礼包集合,特别是数据分析和科学计算方面的库都预装了,也是一个能创建虚拟机环境的工具. 我为什么安装 我安装它的原因不是科学 ...

  10. python BeautifulSoup的使用方法

    BeautifulSoup的使用 我们学习了正则表达式的相关用法,但是一旦正则写的有问题,可能得到的就不是我们想要的结果了,而且对于一个网页来说,都有一定的特殊的结构和层级关系,而且很多标签都有id或 ...