《遇见狂神说》Javaweb之cookie和session

Posted 生命是有光的

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《遇见狂神说》Javaweb之cookie和session相关的知识,希望对你有一定的参考价值。

0、概述

1、cookie

  1. 新建一个mavenweb工程

  2. 在main目录下新建java、resources包

  3. 更新web.xml

  4. 在pom.xml中可以删除packaging标签下方所有

  5. 在pom.xml中导入依赖

    • servlet-api
    • jsp-api
<dependencies>
<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>servlet-api</artifactId>
  <version>2.5</version>
</dependency>
<dependency>
  <groupId>javax.servlet.jsp</groupId>
  <artifactId>jsp-api</artifactId>
  <version>2.1</version>
</dependency>
</dependencies>

1.1、会话

会话:用户打开一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称之为会话;

有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学,曾经来过,称之为有状态会话;

一个网站,怎么证明你来过?

客户端 服务端

  1. 服务端给客户端一个 信件,客户端下次访问服务端带上信件就可以了; cookie
  2. 服务器登记你来过了,下次你来的时候我来匹配你; seesion

1.2、保存会话的两种技术

cookie

  • 客户端技术 (响应,请求)

session

  • 服务器技术,利用这个技术,可以保存用户的会话信息? 我们可以把信息或者数据放在Session中!

常见场景:网站登录之后,你下次不用再登录了,第二次访问直接就上去了!

2、cookie对象

概念:客户端会话技术,将数据保存到客户端

2.1、cookie的创建和发送

使用步骤:

  1. 创建Cookie对象

    • new Cookie(String name,String value)
  2. 将 cookie 添加到 response 对象中

    • resp.addCookie(cookie)

    • 此时该 cookie对象则随着响应发送至了客户端,在浏览器上可以看见

// 创建Cookie对象
Cookie cookie = new Cookie("uname","zhangsan");
// 发送Cookie对象
response.addCookie(cookie);

2.2、cookie的获取

​ 在服务器端只提供了一个 getCookies() 的方法用来获取客户端回传的所有 cookie 组成的一个数组,如果需要获取单个 cookie ,则需要通过遍历,getName() 获取 Cookie 的名称,getValue() 获取Cookie 的值

  • 获取cookie的名称:cookie.getName()
  • 获取cookie的值:cookie.getValue()
  • 获取cookie数组:req.getCookies()
// 获取 Cookie 数组
Cookie[] cookies = request.getCookies();
// 判断数组是否为空
if(cookies != null && cookies.length >0){
    // 遍历Cookie数组:方式一
    for(Cookie cookie : cookies){
        System.out.println(cookie.getName());
        System.out.println(cookie.getValue());
    }
}

2.3、cookie设置到期时间

  • 除了 Cookie 的名称和内容外,我们还需要关心一个信息,到期时间
  • 到期时间:到期时间用来指定该 cookie 何时失效,默认为当前浏览器关闭即失效
  • 我们可以手动设定 cookie 的有效时间(通过到期时间计算)
  • 通过 setMaxAge(int time) 方法设定 cookie 的最大有效时间,以秒为单位。

2.4、到期时间的取值

  • 负整数

    若为负数,表示不存储该 cookie

    cookie 的 maxAge 属性的默认值就是 -1 ,表示只在浏览器内存中存活,一旦关闭浏览器窗口,那么 cookie 就会消失

  • 正整数

    若大于0的整数,表示存储的秒数

    表示 cookie 对象可存货指定的秒数。当生命大于 0 时,浏览器会把 Cookie 保存到硬盘上,就算关闭浏览器,就算重启客户端电脑,cookie 也会存活相应的时间

  • 若为0,表示删除该 cookie

    也就是说,如果原来的浏览器已经保存了这个 Cookie,那么可以通过 Cookie 的 setMaxAge(0) 来删除这个Cookie

Cookie cookie = new Cookie("uname","zhangsan");
cookie.setMaxAge(30);  //表示存活30s
resp.addCookie(cookie);

2.5、cookie编码

  1. Cookie保存在当前浏览器中

    在一般的站点中常常有记住用户名这样一个操作,该操作只是将信息保存在本机上,换电脑以后这些信息就失效了,而且 cookie 还不能跨浏览器

  2. Cookie 存中文问题

    Cookie 中不能出现中文,如果有中文

  • 通过URLEncoder.encode()来编码,
  • 获取时通过URLDecoder.decode() 来进行解码
String name = "姓名";
String value = "张三";
// 通过 URLEncoder.encode() 来进行编码
name = URLEncoder.encode(name);
value = URLEncoder.encode(value);
// 创建 Cookie 对象
cookie cookie = new Cookie(name,value);
// 发送 Cookie 对象
resp.addCookie(cookie);



// 获取时通过URLDecoder.decode()来进行解码
URLDecoder.decode(cookie.getName());
URLDecoder.decode(cookie.getValue());
  1. 同名Cookie问题

    如果服务器端发送重复的Cookie,那么会覆盖原有的Cookie

  2. 浏览器存放Cookie的数量

    • 一个Cookie只能保存一个信息

    • 一个web站点可以给浏览器发送多个cookie,最多存放20个cookie

    • Cookie大小有限制4kb

3、session

  1. 什么是session?
    • 服务器会给每一个用户(浏览器)创建一个Seesion对象
    • 一个Seesion独占一个浏览器,只要浏览器没有关闭,这个Session就存在
    • 服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中

3.1、快速入门

  1. 获取HttpSession对象
    • req.getSession() 获取Session对象
  2. 使用HttpSession对象
    • session.setAttribute(String name,object) 设置session域对象
    • session.removeAttribute(String name) 移除指定名称的session域对象

3.2、session域对象

​ Session 用来表示一次会话,在一次会话中数据是可以共享的,这时 session 作为域对象存在,可以通过setAttribute(name,value) 方法向域对象中添加数据,通过getAttribute(name)从域对象中获取数据,通过removeAttribute(name)从域对象中移除数据

  • session.getId() 获取session的ID
  • session.isNew() 判断是否是新的session对象
//  得到Session
HttpSession session = req.getSession();
//	给Session中存东西 
session.setAttribute("name","狂神说");
//	获取Session的ID
String id = session.getId();
// 判断Session是不是新创建的
session.isNew();
  • 数据存储在 session 域对象中,当session对象不存在了,或者是两个不同的session对象时,数据也就不能共享了。

3.3、例子

3.3.1、例一

  1. 我们给session中存入一个字符串,并在另一个session中拿到数据

SessionDemo01.java

public class SessionDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 解决乱码问题
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=UTF-8");
        // 得到Session
        HttpSession session = req.getSession();
        // 给Session中存东西
		session.setAttribute("name","狂神说");
        // 获取Session的ID
        String id = session.getId();
        // 判断Session是不是新创建的
        if(session.isNew()){
            resp.getWriter().write("session创建成功,ID:" + id);
        }else {
            resp.getWriter().write("session已经在服务器中存在了,ID:" + id);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  • 在web.xml中注册servlet映射为 /s1
<servlet>
    <servlet-name>SessionDemo01</servlet-name>
    <servlet-class>com.kuang.servlet.SessionDemo01</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>SessionDemo01</servlet-name>
    <url-pattern>/s1</url-pattern>
</servlet-mapping>
  • 测试启动

在这里插入图片描述

当浏览器打开时,会自动创建一个session对象,此时session已经存在

  1. 我们在另一个session对象中拿到第一个session中存入的数据

SessionDemo02.java

public class SessionDemo02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 解决乱码问题
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=UTF-8");
        // 得到Session
        HttpSession session = req.getSession();
        // 获取第一个session中存入的数据 name
	    String name = (String) session.getAttribute("name");

        resp.getWriter().write(name);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  • 在web.xml中注册servlet映射为 /s2
<servlet>
    <servlet-name>SessionDemo02</servlet-name>
    <servlet-class>com.kuang.servlet.SessionDemo02</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>SessionDemo02</servlet-name>
    <url-pattern>/s2</url-pattern>
</servlet-mapping>
  • 访问测试

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3.3.2、例二

我们给session中存入一个对象,并在另一个session中拿到数据

  1. 我们新建包 pojo
  2. 在包 pojo 下新建 Person类
public class Person {
    private String name;
    private int age;



    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\\'' +
                ", age=" + age +
                '}';
    }

}

SessionDemo01.java

public class SessionDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 解决乱码问题
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=UTF-8");
        // 得到Session
        HttpSession session = req.getSession();
        // 给Session中存东西 此时存入一个对象
		session.setAttribute("name",new Person("秦将",1));
        // 获取Session的ID
        String id = session.getId();
        // 判断Session是不是新创建的
        if(session.isNew()){
            resp.getWriter().write("session创建成功,ID:" + id);
        }else {
            resp.getWriter().write("session已经在服务器中存在了,ID:" + id);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

SessionDemo02.java

public class SessionDemo02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 解决乱码问题
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=UTF-8");
        // 得到Session
        HttpSession session = req.getSession();
        // 获取第一个session中存入的数据 
	    Person person = (Person) session.getAttribute("name");

        resp.getWriter().write(person.toString());
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  • 访问测试

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3.4、原理

Session的实现是依赖于Cookie的。

3.5、session对象的销毁

3.5.1默认时间到期

  • 当客户端第一次请求 servlet 并且操作 session 时,session 对象生成,Tomcat 中 session 默认的存活时间为 30min
  • 那么 session 的默认时间可以改吗?答案是肯定的
  • 可以在 Tomcat 中 conf 目录下的 web.xml 文件中进行修改
<!--session 默认的最大不活动时间。单位:分钟-->
<session-config>
    <session-timeout>30</session-timeout>
</session-config>

3.5.2自己设定到期时间

  • session.setMaxInactiveInterval(int) :设定session存活时间(单位为秒)
  • session.getMaxInactiveInterval(): 查看当前session存活时间
// 获取session对象
HttpSession session = request.getSession();
// 设置session的最大不活动时间
session.setMaxInactiveInterval(15); // 15秒

以上是关于《遇见狂神说》Javaweb之cookie和session的主要内容,如果未能解决你的问题,请参考以下文章

《遇见狂神说》Javaweb之jsp技术

遇见狂神说---JavaWeb部分笔记

遇见狂神说 --- [ 文件上传,邮件发送实现 ]

遇见狂神说JAVA笔记 --- Mybatis 学习

遇见狂神说--记录MySql部分笔记

《遇见狂神说》全套JDBC技术总结