javaweb学习(day09-Web开发会话技术)

一、会话

1 基本介绍

1.1 什么是会话?

会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个 web 资源,然 后关闭浏览器,整个过程称之为一个会话。

1.2 会话过程中要解决的一些问题? 

1) 每个用户在使用浏览器与服务器进行会话的过程中,不可避免各自会 产生一些数据 ,服
务器要想办法为 每个用户 保存这些数据
2) 例如:多个用户点击超链接通过一个 servlet 各自购买了一个商品,服务器应该想办法
把每一个用户购买的商品保存在各自的地方,以便于这些用户点结帐 servlet 时,结帐
servlet 可以得到用户各自购买的商品为用户结帐

2 会话的两种技术

Session 和 Cookie

二、Cookie

1.Cookie 有什么用

思考问题 1-抛砖引玉

大家在访问某个网站的时候,是否能看到提示你上次登录网站的时间 , 而且要注意的是不同 用户上次登录的时间肯定是不一样的,这是怎么实现的 ?

 思考问题 2-抛砖引玉

大家在访问某个购物网站的时候,是否能看到提示你曾经浏览过的商品,不同用户浏览过
的商品肯定不一样,这是怎么实现的

解决之道—cookie 技术 

Cookie( 小甜饼 ) 是客户端技术,服务器把每个用户的数据以 cookie 的形式写给用户各自的浏 览器。当用户使用浏览器再去访问服务器中的 web 资源时,就会带着各自的数据去。这样 web 资源处理的就是用户各自的数据了。【简单示意图】

 2 cookie 介绍

2.1 二说 cookie

  • Cookie 是服务器在客户端保存用户的信息,比如登录名,浏览历史等, 就可以,以 cookie方式保存
  • Cookie 信息就像是小甜饼(cookie 中文)一样,数据量并不大,服务器端在需要的时候可以从客户端/浏览器读取(http 协议),可以通过图来理解

  • cookie 数据是保存在浏览器的 

 2.2 cookie 可以用来做啥

  • 保存上次登录时间等信息
  • 保存用户名,密码, 在一定时间不用重新登录

  • 网站的个性化,比如定制网站的服务,内容 

cookie 基本使用 

3.1 cookie 常用方法 

  • Cookie 有点象一张表(K-V),分两列,一个是名字,一个是值,数据类型都是 String ,

  • 如何创建一个 Cookie(在服务端创建的) 

  • 如何将一个 Cookie 添加到客户端 

  •  如何读取 cookie(在服务器端读取到 cookie 信息)

 4 cookie 底层实现机制-创建和读取 Cookie

4.1 创建

package com.hspedu.cookie;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class CreateCookie extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("CreateCookie被调用.....");
        //1.创建一个cookie对象
        //username 该cookie的名字是唯一的
        //linran 是该cookie的值 可以创建多个cookie
        //这是cookie在服务器端
        Cookie cookie = new Cookie("username", "linran");
        //2 将cookie发送到浏览器
        response.addCookie(cookie);
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer =response.getWriter();
        writer.println("<h1>创建cookie成功</h1>");
        writer.flush();
        writer.close();

    }
}

 记得导入jar包、配置xml、配置tomcat哦

4.2 读取

package com.hspedu.cookie;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 读取浏览器的cookie信息
 */
public class ReadCookie extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("ReadCookie被调用.....");
        //1 通过request读取cookie对象
        Cookie[] cookies = request.getCookies();
        if(cookies!=null&&cookies.length!=0){
            for (Cookie cookie : cookies) {
                System.out.println("cookie name = "+cookie.getName()+" value = "+cookie.getValue());
            }
        }
        response.setContentType("text/html;charset=utf-8");
        //3 给浏览器返回信息
        PrintWriter writer = response.getWriter();
        writer.println("<h1>读取信息成功</h1>");
        writer.flush();
        writer.close();



    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}
不同会话, jsessionid 不同;

cookie 应用实例 

5.1 读取指定 Cookie 

创建工具类

package com.hspedu.cookie;

import javax.servlet.http.Cookie;

public class CookieUtils {
    //编写一个方法返回指定名字的cookie的值
    public static Cookie readCookieByName(String name,Cookie [] cookies){

        //判断传入的参数是否正确
        if(name==null || "".equals(name) ||cookies==null||cookies.length==0){
            return null;
        }else {
            //遍历cookie数组
            for (Cookie cookie : cookies) {
                if(name.equals(cookie.getName())){
                    return cookie;
                }
            }
        }
        return null;
    }
}
package com.hspedu.cookie;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class ReadCookieByNameServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("ReadCookieByNameServlet被调用.....");
        //得到指定cookie的value
        //先获得浏览器携带的所有cookie

        Cookie[] cookies = request.getCookies();

        //使用工具类获取指定的cookie
        Cookie email =CookieUtils.readCookieByName("email",cookies);
        if(email!=null){
            System.out.println("cookie name = "+email.getName()+" value = "+email.getValue());
        }else {
            System.out.println("没有这个cookie");
        }
        //返回这个信息给浏览器
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.println("<h1>完成读取cookie的信息");
        writer.flush();
        writer.close();

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

5.2 修改 Cookie

package com.hspedu.cookie;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class UpdateCookieServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("UpdateCookieServlet被调用........");
        //根据名字查找cookie
        String cookName="email";
        Cookie[] cookies = request.getCookies();
        Cookie cookie=CookieUtils.readCookieByName(cookName,cookies);
        if(cookie==null){
            System.out.println("当前访问服务端的浏览器没有该cookie");
        }else {
            cookie.setValue("newlinran@baidu.com");
            response.addCookie(cookie);
        }
        //遍历cookie
        System.out.println("修改后的cookie");
        for (Cookie cookie1 : cookies) {
            System.out.println("cookie name = "+cookie1.getName()+" value = "+cookie1.getValue());
        }
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.println("<h1>更新任务完成</h1>");
        writer.flush();
        writer.close();

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

 6 cookie 生命周期

6.1 介绍 

  • Cookie 的生命周期指的是如何管理 Cookie 什么时候被销毁(删除) 
  • setMaxAge() 

 6.2 应用实例

package com.hspedu.cookie;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class CookieLiveServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("CookieLiveServlet被调用");

        //演示创建一个cookie 生命周期为60秒
        Cookie cookie =new Cookie("job","java");
        //1 从创建该Cookie计时 60秒后无效
        //2 浏览器来根据创建的时间,计时到60秒,就认为该cookie无效
        //3 如果该cookie无效,那么浏览器在发http请求时,就不再携带该cookie
        cookie.setMaxAge(60);
        //4 将cookie保存到浏览器
        response.addCookie(cookie);

        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.println("<h1>设置cookie生命周期成功</h1>");
        writer.flush();
        writer.close();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request,response);
    }
}

cookie 有效路径

  • Cookie 有效路径 Path 的设置
  • Cookie path 属性可以有效的过滤哪些 Cookie 可以发送给服务器。哪些不发。 path属性是通过请求的地址来进行有效的过滤
  • 规则如下

作业 

  • 需求: 完成自动填写登录账户应用案例 , 如果用户登录成功,则下次登录自动填写登录账户(如图
  •  如果用户名是 linran, 密码是 123456, 则认为该用户合法, 登录成功,否则登录失败
  • 要求实现如果登录成功,则该用户,在 3 天内登录,可以自动填写其登录名
  • 登录页面需要使用 servlet 返回,而不能使用 html

 

package com.hspedu.cookie;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class UserUiServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("UserUiServlet被调用.......");
        //读取cookie
        Cookie[] cookies = request.getCookies();
        Cookie username_cookie = CookieUtils.readCookieByName("username", cookies);
        Cookie password_cookie =CookieUtils.readCookieByName("password",cookies);
        String username="";
        String password="";
        if(username_cookie!=null){//如果有
            username=username_cookie.getValue();
        }
        if(password_cookie!=null){
            password=password_cookie.getValue();
            System.out.println(password);
        }

        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.println("<!DOCTYPE html>\n" +
                "<html lang=\"en\">\n" +
                "<head>\n" +
                "    <meta charset=\"UTF-8\">\n" +
                "    <title>登录页面</title>\n" +
                "</head>\n" +
                "<body>\n" +
                "<h1>用户登录界面</h1>\n" +
                "<form action=\"/cs/loginServlet\">\n" +
                "    u:<input type=\"text\" name=\"username\" value=\""+username+"\"><br>\n" +
                "    p:<input type=\"password\" name=\"password\" value=\""+password+"\"><br>\n" +
                "    <input type=\"submit\" value=\"登录\">\n" +
                "</form>\n" +
                "</body>\n" +
                "</html>");
        writer.flush();
        writer.close();

    }


    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}
package com.hspedu.cookie;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("LoginServlet被调用");
        //接收表单提交的用户名和密码
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();



        //判断是否合法
        if("linran".equals(username)&& "123456".equals(password)){
            //将登录成功的用户名和密码以cookie的形式进行保存
            Cookie username1 = new Cookie("username", username);
            //设置生命周期
            username1.setMaxAge(3600*24*3);
            Cookie password1 = new Cookie("password", password);
            password1.setMaxAge(3600*24*3);
            response.addCookie(username1);
            response.addCookie(password1);
            //合法
            writer.println("<h1>登录成功</h1>");



        }else {
            writer.println("<h1>登录失败</h1>");
        }


    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

Cookie 注意事项和细节

  • 一个 Cookie 只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)。
  • 一个 WEB 站点可以给一个浏览器发送多个 Cookie,一个浏览器也可以存储多个 WEB 点提供的 Cookie
  • cookie 的总数量没有限制,但是每个域名的 COOKIE 数量和每个 COOKIE 的大小是有限 制的 (不同的浏览器限制不同, 知道即可) , Cookie 不适合存放数据量大的信息。
  • 注意,删除 cookie 时,path 必须一致,否则不会删除
  •  Java servlet cookie 中文乱码解决[设置编码+解码】
  • 如果存放中文的 cookie, 默认报错, 可以通过 URL 编码和解码来解决, 不建议存 放中文的 cookie 信息

三、session 

1. session 有什么用 

  • 不同的用户登录网站后,不管该用户浏览该网站的哪个页面,都可显示登录人的名字,还可以随时去查看自己的购物车中的商品, 是如何实现的?
  • 也就是说,一个用户在浏览网站不同页面时,服务器是如何知道是张三在浏览这个页面,还是李四在浏览这个页面?

 解决之道—session 技术, 简单说

  • Session 是服务器端技术,服务器在运行时为每一个用户的浏览器创建一个其独享的session 对象/集合
  • 由于 session 为各个用户浏览器独享,所以用户在访问服务器的不同页面时,可以从各自session 中读取/添加数据, 从而完成相应任务

 2 session 基本原理

2.1 Sesson 原理示意图 

 

  • 当用户打开浏览器,访问某个网站, 操作 session 时,服务器就会在内存(在服务端)为该浏览器分配一个 session 对象,该 session 对象被这个浏览器独占, 如图
  • 这个 session 对象也可看做是一个容器/集合,session 对象默认存在时间为 30min(这是在tomcat/conf/web.xml),也可修改 

 2.2 Session 可以做什么

  • 网上商城中的购物车
  • 保存登录用户的信息
  • 将数据放入到 Session 中,供用户在访问不同页面时,实现跨页面访问数据
  • 防止用户非法登录到某个页面 
  • ......

2.3 如何理解 Session 

  • session 存储结构示意图 

  • 你可以把 session 看作是一容器类似 HashMap,有两列(K-V),每一行就是 session 的一个属性。
  • 每个属性包含有两个部分,一个是该属性的名字(String),另外一个是它的值(Object) 

3 session 常用方法 

Session 的基本使用
  • 创建和获取 SessionAPI 一样

  •  session 添加属性

 

  • session 得到某个属性 

 

  • session 删除调某个属性: 

  •  isNew(); 判断是不是刚创建出来的 Session
  • 每个 Session 都有 1 个唯一标识 Id 值。通过 getId() 得到 Session 的会话 id

4 session 底层实现机制 

4.1 原理分析图 

 

 4.2 代码演示

演示 Session 底层实现机制-创建和读取 Session 

创建

package com.hspedu.session;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;

public class CreatSession extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("CreatSession被调用......");

        //获取session 同时也可能创建Session
        HttpSession session = request.getSession();
        //给session获取id
        System.out.println("当前sessionId= "+session.getId());
        //给session存放数据
        session.setAttribute("email","zs@qq.com");

        //给浏览器一个回复
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer =response.getWriter();
        writer.println("<h1>创建session成功</h1>");
        writer.flush();
        writer.close();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

 读取

package com.hspedu.session;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;

public class ReadSessionServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("ReadSessionServlet被调用......");

        //演示读取Session
        //如果没有也会被创建
        HttpSession session = request.getSession();
        Object email = session.getAttribute("email");
        if(email!=null){
            System.out.println("session属性 email= "+(String) email);
        }else {
            System.out.println("session没有email属性");
        }
        //给浏览器一个回复
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer =response.getWriter();
        writer.println("<h1>读取session成功</h1>");
        writer.flush();
        writer.close();

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

5 session 生命周期

5.1 Session 生命周期-说明 

  • public void setMaxInactiveInterval(int interval) 设置 Session 的超时时间(以秒为单位),
  • 超过指定的时长,Session 就会被销毁。
  • 值为正数的时候,设定 Session 的超时时长。
  • 负数表示永不超时
  • public int getMaxInactiveInterval()获取 Session 的超时时间
  • public void invalidate() 让当前 Session 会话立即无效
  • 如果没有调用 setMaxInactiveInterval() 来指定 Session 的生命时长,Tomcat 会以Session默认时长为准,Session 默认的超时为 30 分钟, 可以在 tomcat web.xml 设置

 

  • Session 的生命周期指的是 :客户端/浏览器两次请求最大间隔时长,而不是累积时长即当客户端访问了自己的 sessionsession 的生命周期将从 0 开始重新计算。(解读: 的是同一个会话两次请求之间的间隔时间)
  • 底层: Tomcat 用一个线程来轮询会话状态,如果某个会话的空闲时间超过设定的最大值,则将该会话销毁

5.2 Session 生命周期-应用实例 

创建

package com.hspedu.session;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;

public class CreateSession2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("CreateSession2被调用.....");
        //创建session
        HttpSession session = request.getSession();
        System.out.println("CreateSession2 sid= "+session.getId());
        //设置生命周期
        session.setMaxInactiveInterval(60);
        //添加属性
        session.setAttribute("u","jack");


        //给浏览器一个回复
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer =response.getWriter();
        writer.println("<h1>创建session2成功,设置生命周期60s</h1>");
        writer.flush();
        writer.close();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

 读取

package com.hspedu.session;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;

public class ReadSession2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("ReadSession2被调用.....");
        //获取session
        HttpSession session = request.getSession();
        System.out.println("ReadSession2 sid= "+session.getId());
        String res="";
        //读取session的属性
        Object u = session.getAttribute("u");
        if(u!=null){
            System.out.println("读取到session属性 u= "+(String) u);
            res="读取到session属性 u= "+(String) u;
        }else {
            System.out.println("读取不到session属性 u 说明原来session被销毁");
            res="读取不到session属性 u 说明原来session被销毁";
        }

        //给浏览器一个回复
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer =response.getWriter();
        writer.println("<h1>"+res+"</h1>");
        writer.flush();
        writer.close();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

删除

package com.hspedu.session;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;

public class DeleteSession extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("DeleteSession被调用.....");
        HttpSession session = request.getSession();
        session.invalidate();
        //给浏览器一个回复
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer =response.getWriter();
        writer.println("<h1>删除session成功</h1>");
        writer.flush();
        writer.close();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }
}

  • 27
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜菜小林然

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值