我的编程空间,编程开发者的网络收藏夹
学习永远不晚

详解Javaweb状态管理的Session和Cookie

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

详解Javaweb状态管理的Session和Cookie

问题引入

  • HTTP协议是无转态的,不能保存提交的信息
  • 如果用户发来一个新的请求,服务器无法知道它是否与上次的请求联系
  • 对于那些需要多次提交数据才能完成的web操作,比如登录,就难以完成

概念

将浏览器与web服务器之间多次交互当做一个整体来处理,并且多次交互所涉及的数据(状态)保存下来

状态管理分类

  • 客户端状态管理技术:将转态保存在客户端,代表性的是Cooklie技术
  • 服务器状态管理技术:将状态保存在服务器端,代表性的是session技术(服务器传递session时需要使用Cookie的方式)和application

Cookie

  • Cookie是浏览器访问Web服务器某个资源时,由Web服务器在HTTP响应消息头中附带传送给浏览器的小段数据
  • 一旦Web服务器保存了某个Cookie,那么它在以后每次访问该Web服务器时,都应在HTTP请求中将这个Cookie回传给Web服务器
  • 一个Cookie主要由标识该信息的名称name和值value组成

Cookie的创建、获取、修改

Cookie创建
@WebServlet(value = "/cs")
public class CookieServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //服务端创建Cookie对象
        Cookie cookie = new Cookie("username","weishuo");
        //设置Cookie的访问路径
        cookie.setPath("/Servlet_Projects_war/get");
        //设置Cookie的有效期  >0有效期,单位秒 =0浏览器关闭 <0内存存储  默认-1
        cookie.setMaxAge(60*60);    //1小时
        //添加到response对象中,将Cookie响应给客户端
        resp.addCookie(cookie);     //将Cookie添加到response对象中,响应给客户端
    }
}
Cookie获取
@WebServlet(value = "/get")
public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //通过request对象获取所有的cookie
        Cookie[] cookies = req.getCookies();
        if (cookies!=null){         //判断cookies数组是否为空,避免空指针异常
            //通过循环遍历Cookie
            for (Cookie cookie : cookies) {
                System.out.println(cookie.getName() + ":" + cookie.getValue());
            }
        }
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
Cookie修改

如果修改Cookie的name和有效路径会新建cookie,而改变Cookie值,有效期会覆盖原有的Cookie

@WebServlet(value = "/cs2")
public class CookieServlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //服务端创建Cookie对象
        Cookie cookie = new Cookie("username","given");
        //设置Cookie的访问路径
        cookie.setPath("/Servlet_Projects_war/get");
        //设置Cookie有效期
        cookie.setMaxAge(60*60*24*7);   //7天
        //添加到response对象中,将Cookie响应给客户端
        resp.addCookie(cookie);
    }
}

Cookie编码与解码

Cookie默认不支持中文,只能包含ASCII字符,所以Cookie需要对Unicode字符进行编码,否则会出现乱码

  • 编码可以使用java.net.URLEncoder类encode(String str,String encoding)方法
  • 解码使用java.net.URLDecoder类decode(String str,String encoding)方法
//Cookie设置
@WebServlet(value = "/cs3")
public class CookieServlet3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //服务端创建Cookie对象,使用Cookie编码
        Cookie cookie = new Cookie(URLEncoder.encode("姓名","UTF-8"),URLEncoder.encode("张三","UTF-8"));
        //设置Cookie的访问路径
        cookie.setPath("/Servlet_Projects_war/get");
        //设置Cookie有效期
        cookie.setMaxAge(600);
        //添加到response对象中,将Cookie响应给客户端
        resp.addCookie(cookie);
    }
}
//Cookie读取
@WebServlet(value = "/get")
public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //通过request对象获取所有的cookie
        Cookie[] cookies = req.getCookies();
        if (cookies!=null){         //判断cookies数组是否为空,避免空指针异常
            //通过循环遍历Cookie
            for (Cookie cookie : cookies) {
                //使用Cookie解码
                System.out.println(URLDecoder.decode(cookie.getName(),"UTF-8") + ":" + URLDecoder.decode(cookie.getValue(),"UTF-8"));
            }
        }
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

总结

Cookie优点

可配置到期规则Cookie是一种基于文本的轻量级结构,包含简单的键值对Cookie默认在过期之前是可以一直存在在客户端浏览器上

Cookie的缺点

大小受到限制,浏览器对Cookie大小有4K,8K字节限制用户配置为禁用,用户禁用了浏览器或客户端接受Cookie的能力Cookie可能被篡改,存在潜在风险

Session

概述

  • Session用于记录用户的状态,Session指的是一段时间,单个客户端与web服务器的一连串交互过程
  • 一个Session中,客户可能会多次请求访问同一个资源,也可能请求访问各种不同的服务器资源

原理

Tip:

Session和Cookie都是由服务器端创建

  • 服务器为每一次会话分配一个Session对象
  • 同一个浏览器发起的多次请求,同属于一次会话(Session)
  • 首次使用Session,服务器自动创建Session,并且创建Cookie存储SessionID发送回客户端

session使用

Session作用域:拥有存储数据的空间,作用范围是一次会话有效

  • 一次会话是使用同一浏览器发送到多次请求,浏览器关闭则会话结束
  • 可以将数据存入Session中,一次会话的任意位置进行获取
  • 可以传递任何数据(基本数据类型、对象、集合、数组)

获取session

//获取Session对象
HttpSession session = request.getSession();
System.out.println("id"+session.getId());	//唯一标识
package com.woniu.sessions;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "Servlet", value = "/ss")
public class Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //通过request对象获取session对象
        HttpSession session = request.getSession();
        System.out.println(session.getId());
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

Session保存数据

  • 保存数据到session中

setAttribute(属性名,Objects);

session.setAttribute("key",value);//以键值对形式存储在session作用域中

Session获取数据

  • 获取session中数据

getAttribute(属性名);

session.getAttribute("key");	//通过String类型的key访问Object类型的value

Session移除数据

  • 从Session中删除数据

removeAttribute(属性名);

session.removeAttribute("key");//通过移除session作用域中的值

应用

  • Servlet类
@WebServlet(name = "Servlet", value = "/ss")
public class Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //通过request对象获取session对象
        HttpSession session = request.getSession();
        //使用session保存数据
        session.setAttribute("username","given");
        //通过产生的session对象获取sessionId
        System.out.println(session.getId());
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}
  • GetValueServlet类
@WebServlet(name = "GetValueServlet", value = "/getValue")
public class GetValueServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        String username = (String) session.getAttribute("username");
        System.out.println("从session中获得了" + username);  //从session中获得了given
    }
}
  • RemoveServlet类
@WebServlet(name = "RemoveServlet", value = "/remove")
public class RemoveServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        session.removeAttribute("username");
    }
}
  • 结果
543D0EA33CB586691A02C00564E34CEA
从session中获得了given
从session中获得了null

Session & Request 区别

  • request是一次请求有效,请求改变,则request改变
  • session是一次会话有效,浏览器改变,则session改变

SessionServlet类

@WebServlet(name = "Servlet", value = "/ss")
public class SessionServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //通过request对象获取session对象
        HttpSession session = request.getSession();
        //使用session保存数据
        session.setAttribute("username","given");
        //使用request保存数据
        request.setAttribute("password",123456);
        //重定向跳转到/getValue
        response.sendRedirect("/Servlet_Projects_war/getValue");
        //通过产生的session对象获取sessionId
        System.out.println(session.getId());
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}
GetValueServlet类
@WebServlet(name = "GetValueServlet", value = "/getValue")
public class GetValueServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        String password = (String) request.getAttribute("password");
        System.out.println("从request中获得了" + password);
        String username = (String) session.getAttribute("username");
        System.out.println("从session中获得了" + username);  //从session中获得了given
    }
}
结果
从request中获得了null
从session中获得了given

总结

sendRedirect跳转时,地址栏发生改变,代表客户端重新发送请求,属于两次请求;response没有作用域,两次request请求中的数据无法共享;而session只要浏览器不关闭属于一次会话,一次会话中浏览器数据可以共享

Session生命周期

  • 开始:第一次使用到Session的请求产生,则创建Session
  • 结束
  • 浏览器关闭,则失效
    • Session超时,则失效
      • session.SetMaxInactivelnterval(seconds); 设置最大有效时间(单位/秒)
    • 手工销毁,则失效
      • session.invalidate(); 登录退出、注销
LifeSessionServlet类
@WebServlet(name = "LifeSessionServlet", value = "/life")
public class LifeSessionServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doPost(request, response);
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取session
        HttpSession session = request.getSession();
        //设置session有效过期时间为10s
        session.setMaxInactiveInterval(10);
        //通过产生的session对象获取sessionId
        System.out.println(session.getId());
    }
}
GetSessionServlet类
@WebServlet(name = "GetSessionServlet", value = "/getSession")
public class GetSessionServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doPost(request, response);
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取session
        HttpSession session = request.getSession();
        System.out.println(session.getId());
        //手工销毁,立即失效
        //session.invalidate();
    }
}
结果
浏览器输入/life,获取到的sessionId
71A9B2141F22840E0BE7EA67B49EC9B3
10秒内,浏览器输入/getSession,获取到的sessionId
71A9B2141F22840E0BE7EA67B49EC9B3
10秒后,浏览器输入/getSession,获取到的sessionId
EDF2E31978DE8295486C2657016F5202

浏览器禁用Cookie解决方案

浏览器禁用Cookie后果

服务器在默认情况下,会使用Cookie的方式将sessionID发送给服务器,如果用户禁止Cookie,则sessionID不会被浏览器保存,此时,服务器使用如URL重写这样的方式来发送sessionID

URL重写

浏览器在访问服务器上的某个地址时,不再使用原来的那个地址,而是使用经过改写的地址(即在原来的地址后面加上sessionID)

实现URL重写

  • response.encodeRedirectURL(String url); //生成重写的URL
//实现URL重写
String url = response.encodeRedirectURL("/Servlet_Projects_war/getSession");
//输出URL重写地址
System.out.println(url);
//重定向转发
response.sendRedirect(url);
结果
重写URL地址
/Servlet_Projects_war/getSession;jsessionid=A38B1C92B9CDE10F6ED5E7AA19E919F0
浏览器输入/life,获取到的sessionId
A38B1C92B9CDE10F6ED5E7AA19E919F0
重定向转发地址:/Servlet_Projects_war/getSession,获取到的sessionId
A38B1C92B9CDE10F6ED5E7AA19E919F0

到此这篇关于详解Javaweb状态管理的Session和Cookie的文章就介绍到这了,更多相关Javaweb的Session和Cookie内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

详解Javaweb状态管理的Session和Cookie

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

详解Javaweb状态管理的Session和Cookie

这篇文章主要介绍了Javaweb状态管理的Session和Cookie,将浏览器与web服务器之间多次交互当做一个整体来处理,并且多次交互所涉及的数据(状态)保存下来,需要的朋友可以参考下
2023-05-20

详解Vue3-pinia状态管理

这篇文章主要介绍了Vue3-pinia状态管理,pinia是 vue3 新的状态管理工具,简单来说相当于之前 vuex,它去掉了 Mutations 但是也是支持 vue2 的,需要的朋友可以参考下
2022-11-13

Laravel操作session和cookie的教程详解

这篇文章主要为大家详细介绍了Laravel操作session和cookie的教程,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的小伙伴可以了解一下
2023-02-09

ReactNative 状态管理redux使用详解

这篇文章主要介绍了ReactNative 状态管理redux使用详解
2023-03-10

一文详解Electron电源状态管理

这篇文章主要为大家介绍了Electron电源状态管理示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-03-10

Flutter状态管理Provider的使用示例详解

这篇文章主要为大家介绍了Flutter状态管理Provider的使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-11-13

Mobx实现React 应用的状态管理详解

这篇文章主要为大家介绍了Mobx 实现 React 应用的状态管理,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-12-08

Flutter状态管理Bloc使用示例详解

这篇文章主要为大家介绍了Flutter状态管理Bloc使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-11-13

一文详解ReactNative状态管理rematch使用

这篇文章主要为大家介绍了ReactNative状态管理rematch使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-03-10

一文详解ReactNative状态管理redux-toolkit使用

这篇文章主要为大家介绍了ReactNative状态管理redux-toolkit使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-03-10

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录