Cookie&Session

大家好呀,我是小笙,我和大家分享下我学习Javaweb的笔记

Web 开发会话技术

什么是会话?

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

会话的两种技术

Cookie

概念:Cookie 是服务器在客户端保存用户的信息,比如登录名,浏览历史等, 就可以以 cookie 方式保存

cookie框架图

image-20220502160718152

Cookie的作用

  • 保存上次登录时间等信息
  • 保存用户名,密码, 在一定时间不用重新登录
  • 网站的个性化,比如定制网站的服务,内容
读取Cookie数据
  1. 浏览器端创建email=1079936135qq.com的数据

    image-20220502135841666

  2. 浏览器向服务器传输Cookie数据

    image-20220502140445863

  3. 服务器读取到Cookie数据

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Cookie[] cookies = request.getCookies();
        if(cookies != null && cookies.length != 0){
            for (Cookie coke : cookies) {
                //  cookieName: email  cookieValue1079936135
                //  cookieName: Idea-6463f311  cookieValue6cb7445e-85d8-4a31-a12a-bcdbe5c375d9
                // 如果读取到中文名字
                // 可以通过URLDecoder.decode(coke.getName(),"utf-8")解码
                System.out.println("cookieName: " + coke.getName() + "  cookieValue" + coke.getValue());
            }
        }
    }
    
创建Cookie实例

image-20220502135401926

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    System.out.println("cookie被调用");
    // 创建Cookie对象
    // 解决不能存储中文的原因,需要进行url编码
    String data = URLEncoder.encode("罗念笙","UTF-8");
    Cookie cookie = new Cookie("username",data);
    //将Cookie发送给浏览器并保存
    response.addCookie(cookie);
    response.setContentType("text/html;charset=utf-8");
    PrintWriter writer = response.getWriter();
    writer.write("<h1>Cookie创建成功!</h1>");
    writer.flush();
    writer.close();
}
修改Cookie值

image-20220502155708934

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Cookie[] cookies = request.getCookies();
    String cookieName = "email";
    Cookie cookie = CookieUtils.nameToGetCookie(cookieName, cookies);
    CookieUtils.IterCookie(cookies);
    if(cookie == null){
        System.out.println("没有该Cookie");
    }else{
        cookie.setValue("10799361@qq.com");
        CookieUtils.IterCookie(cookies);
        response.addCookie(cookie);
    }
}

// 工具类
public class CookieUtils {
    /**
     * 通过CookieName来获取对应的Cookie
     */
    public static Cookie nameToGetCookie(String cookieName,Cookie[] cookies){
        if(cookieName != null && !cookieName.equals("") && cookies != null && cookies.length != 0){
            for (Cookie cookie : cookies) {
                if(cookie.getName().equals(cookieName)){
                    return cookie;
                }
            }
        }
        return null;
    }

    /**
     * 遍历Cookie,显示Cookie的name-value 
     */
    public static void IterCookie(Cookie[] cookies){
        System.out.println();
        if(cookies != null && cookies.length != 0){
            for (Cookie cookie : cookies) {
                System.out.println("cookieName: " + cookie.getName() + "  cookieValue: " + cookie.getValue());
            }
        }
        System.out.println();
    }
}
cookie 生命周期

常用方法

// 正数,表示在指定的秒数后过期
// 负数,表示浏览器关闭 Cookie 就会被删除(默认值是-1)
// 0,表示马上删除 Cookie (可以用来删除Cookie)
setMaxAge()

代码示例

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // 创建一个新的Cookie对象
    Cookie cookie = new Cookie("age","18");
    // 设置Cookie的生命周期 20s
    cookie.setMaxAge(20);
    // 返回给浏览器存储20s 
    response.addCookie(cookie);
}
cookie 有效路径

Cookie 的 path 属性可以有效的过滤哪些 Cookie 可以发送给服务器,哪些不发。 path 属性是通过请求的地址来进行有效的过滤

// 举例说明 (默认setPath:/工程路径 )
cookie1.setPath = /工程路径 
cookie2.setPath = /工程路径/aaa 
    
// url请求地址: http://ip:端口/工程路径/资源 
cookie1 会发给服务器 
cookie2 不会发给服务器 
    
// url请求地址: http://ip:端口/工程路径/aaa/资源 
cookie1 会发给服务器 
cookie2 会发给服务器

Cookie 注意事项和细节

  1. 一个 Cookie 只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值 (VALUE)

  2. 一个 WEB 站点可以给一个浏览器发送多个 Cookie,一个浏览器也可以存储多个 WEB 站点提供的 Cookie

  3. Cookie 的总数量没有限制,但是每个域名的 Cookie 数量和每个 Cookie的大小是有限制的 (不同的浏览器限制不同) , Cookie 不适合存放数据量大的信息

  4. 注意中文存入cookie的时候需要编码和解码

    // url编码
    String data = URLEncoder.encode("想要存入的中文","UTF-8");
    Cookie cookie = new Cookie("username",data);
    //url解码
    URLDecoder.decode(cookie数据,"utf-8");
    

Session

基本介绍

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

session 对象默认存在时间为 30min

<!-- ==================== Default Session Configuration ================= -->
<!-- You can set the default session timeout (in minutes) for all newly   -->
<!-- created sessions by modifying the value below.                       -->
<!-- Tomcat中web.xml文件可以配置时间,默认30min -->
<session-config>
    <session-timeout>30</session-timeout>
</session-config>

Session的作用

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

session 存储结构示意图

名字(key)值(value)
String类型Object类型
常用方法
// 1.创建和获取 Session
// 第1次调用是创建 Session 会话, 之后调用是获取创建好的 Session 对象 
HttpSession hs=request.getSession(); 
// 2.向 session 添加属性 
hs.setAttribute(String name,Object val); 
// 3.从 session 得到某个属性 
Object obj=hs.getAttribute(String name);
// 4.从 session 删除调某个属性: 
hs.removeAttribute(String name); 
// 5.判断是不是刚创建出来的 Session
hs.isNew(); 
// 6.每个Session都有1个唯一标识Id值,通过getId()得到Session的会话id值(JSESSIONID)
原理示意图

JSESSIONID

用于服务器来标识不同的会话,不同的会话,服务器会对应创建不同的JSESSIONID

image-20220502144731606

框架图

image-20220503185147684

操作代码示例

设置属性

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.setContentType("text/html;charset=utf-8");
    PrintWriter writer = response.getWriter();
    HttpSession session = request.getSession();
    session.setAttribute("id","1234956789");
    System.out.println("属性设置完成");
    writer.flush();
    writer.close();
}

读取属性

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.setContentType("text/html;charset=utf-8");
    PrintWriter writer = response.getWriter();
    HttpSession session = request.getSession();
    Object s = session.getAttribute("id");
    if(s != null){
        System.out.println((String)s);
    }else{
        System.out.println("没有该属性");
    }
    writer.flush();
    writer.close();
}
session 生命周期

Session 的生命周期指的是 :客户端/浏览器两次请求最大间隔时长,而不是累积时长。 即当客户端访问了自己的 session,session 的生命周期将从 0 开始重新计算。(同一个会话两次请求之间的间隔时间)

底层: Tomcat 用一个线程来轮询会话状态,如果某个会话的空闲时间超过设定的最大值, 则将该会话销毁

// 设置 Session 的超时时间(以秒为单位), 超过指定的时长,Session 就会被销毁
// 1.值为正数的时候,设定 Session 的超时时长
// 2.负数表示永不超时
// 3.如果没有调用 setMaxInactiveInterval() 来指定Session的生命时长,Tomcat 会以Session默认时长为准,Session 默认的超时为30分钟,可以在tomcat的web.xml设置;注意Cookie是累计时长,时间一到就会销毁
public void setMaxInactiveInterval(int interval)
// 获取 Session 的超时时间
public int getMaxInactiveInterval()
// 让当前 Session 会话立即无效
public void invalidate()
经典案例

防止非法进入管理页面

  • login.html表单提交给LoginCheckServlet.java
  • 如果验证成功(用户名不为空,密码为 666666,),则进入管理页面 ManageServelt.java,如果验证不成功,跳转到error.html页面
  • 如果用户直接访问 ManageServet.java , 重定向到到 login.html
<!-- login.html -->
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>用户登录</title></head>
    <body><h1>用户登录</h1>
    <form action="/session/loginCheck" method="post">
        用户名:<input type="text" name="username"/><br/><br/>
        密 码:<input type="password" name="password"><br><br/>
        <input type="submit" value="登录">
    </form>
    </body>
</html>

<!-- error.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>登录失败</h1>
    <a href="login.html" style="text-decoration: none">点击返回重新登录</a>
</body>
</html>
// LoginCheckServlet.java
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    if(username != null && password != null){
        if(!"".equals(username) && "666666".equals(password)){
            HttpSession session = request.getSession();
            session.setAttribute("username",username);
            request.getRequestDispatcher("/manageServlet").forward(request,response);
        }else{
            request.getRequestDispatcher("/error.html").forward(request,response);
        }
    }else{
        response.sendRedirect("/login.html");
    }
}

// ManageServlet.java
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    HttpSession session = request.getSession();
    Object username = session.getAttribute("username");
    if(username != null){
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.println("<h1>用户管理页面</h1>");
        writer.println("欢迎你,管理员: " + (String)username);
        writer.flush();
        writer.close();
    }else{
        response.sendRedirect("/session/login.html");
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Al_tair

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

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

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

打赏作者

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

抵扣说明:

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

余额充值