Servlet Cookie、Session
HTTP不能保持连接,可使用会话保存用户信息。
常用的会话技术有2种:Cookie、Session。
Cookie
1、原理
当用户第一次访问某个网站时,服务器设置Cookie,存储用户信息,放在响应头字段中,随HTTP响应传给浏览器,浏览器把Cookie存储到本地计算机上。
当用户再次访问该网站时,浏览器先在本地计算机上查找该网站的Cookie,如果有,放在请求头中,随HTTP请求一起发送给该网站的服务器。服务器解析Cookie,获取该用户的信息,进行相关操作。
服务器可重新设置Cookie,随HTTP响应传递给浏览器,由浏览器更新本地的cookie。
2、常用方法
- Cookie(String name, String value) //构造函数,name、value均为String。创建一个Cookie后,它的name不能被更改。
- Cookie[] cookies = request.getCookies(); //获取请求头中的所有Cookie
- void setValue(String value) //Cookie的name不能被修改,所以没有setName()方法
- void setMaxAge(int expiry) //设置此Cookie的有效期,从当前时间起,在浏览器上多少秒内有效。
缺省时默认只在本次会话期间有效,当我们关闭此浏览器时,会话结束,此Cookie失效,注意是关闭浏览器整个程序,不是关闭浏览器某个窗口。
为0时,浏览器会立即清除此Cookie。
为负整数时,此Cookie只在本次会话期间有效。
- void setPath(String url) //设置此Cookie的作用页面。缺省时默认只对当前页面所在目录有效。
比如包servlet下有一个LoginServlet,我在LoginServlet中设置了一个Cookie,如果不给这个Cookie设置path,则默认此Cookie只在servlet包中有效(servlet包下的所有页面均可使用此Cookie)。设置为全站可用:cookie.setPath("/"),本站所有页面均可使用此Cookie。
这个不常用,因为Cookie一般都是作用于当前网站。
- void setDomain(String domain) //设置此Cookie作用的网站(隶属于哪个网站),缺省时默认为当前网站。
浏览器访问一个url之前,会先根据url中的domain查找本地计算机上所有属于该domain的Cookie,把这些Cookie都加到请求头中,发送给该网站的服务器。
比如我设置一个Cookie的domain为百度: cookie.setDomain(".baidu.com"); (需要去掉www)
浏览器访问百度这个网站上的页面时,会把此Cookie添加到请求头中,随请求一同发送给百度的服务器。
- response.addCookie(Cookie cookie); //把一个Cookie添加到响应头中,这样Cookie才会被传递给浏览器。
- String getName()
- String getValue()
- String getMaxAge()
- String getPath()
- String getDomain()
3、使用示例
@WebServlet("/testServlet")
public class TestServlet 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 {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter(); String name=null;
Cookie[] cookies = request.getCookies();
if(cookies!=null){
for(int i=0;i<cookies.length;i++){ //用增强的for循环写遍历更简单
if(cookies[i].getName().equals("name")){ //获取用户名
name = cookies[i].getValue();
writer.write(cookies[i].getValue()+",你好!");
}
}
}
if(name==null){
writer.write("请先登录,3秒后将自动跳转到登录页面");
response.setHeader("refresh","3;url=./login.jsp");
} }
}
String name="chy"; //注册|登录成功后,从表单获取用户信息,存储到Cookie中。这里只是模拟获取到的用户名。
Cookie cookie=new Cookie("name",name);
cookie.setMaxAge(60*60*24*365); //一年有效
cookie.setPath("/"); //全站可用,本站的所有页面都可以使用此Cookie获取用户名
response.addCookie(cookie); //需要添加到response中才会生效。如果要设置、更新多个Cookie,需要一个一个地添加
4、Cookie的2种更新方式
//遍历,获取指定的Cookie。
for (Cookie cookie:cookies){
if (cookie.getName().equals("name")){
cookie.setValue("chy"); //使用setXxx()修改Cookie
response.addCookie(cookie); //必须使用此句代码才会同步到浏览器
}
}
//使用同名的Cookie来覆盖
Cookie nameCookie=new Cookie("name","chy");
nameCookie.setMaxAge(60*60*24*365);
nameCookie.setPath("/");
response.addCookie(nameCookie);
Cookie存储的是一个键值(name/value)对,浏览器端存储的Cookie由键(name)唯一标识。所以可以使用同名覆盖来更新Cookie。
但新创建的Cookie,如果不设置maxAge、path,会使用默认值。如果只更新Cookie的value,还需要设置maxAge、path,以确保maxAge、path不变。
5、在Chrome中查看当前网站Cookie的4种方式
(1)点击地址栏中的带圈的i或者小锁
小锁表示此网站是安全的,带圈的i表示此网站是不安全的。
点击某个Cookie,再点删除,可删除该Cookie。
点击该网站的域名,再点删除,会删除该网站所有的Cookie。
点击该网站的域名,再点禁止,该网站不能在此计算机上存储Cookie(浏览器会自动删除该网站已存储的Cookie)。
(2)f12 -> Application -> Storage -> Cookies
(3)f12 -> Console -> 输入 document.cookie 可查看本网站所有的Cookie,输入 document.cookie="" 即可修改Cookie。
这种方式设置的是整个网站的Cookie,不是某个Cookie。所以一般是把document.cookie得到的值复制下来,修改里面的某些Cookie,然后以字符串的形式赋给document.cookie。
(4)设置 -> 高级 -> 隐私设置和安全性 -> 网站设置 -> Cookie -> 查看所有Cookie和网站数据
说明
- Cookie由浏览器自己存储,各浏览器之间不共享Cookie。
比如我在Chrome中打开了某网站,该网站在Chrome中存储了Cookie,这些Cookie算是Chrome的私有数据,其它浏览器读取不到(不会共享给其它浏览器)。
- 有时,浏览器会自动给一些网站设置一些额外的Cookie,比如_ga,_gid。
Session
1、原理
使用Cookie把会话信息保存在浏览器上,每次HTTP请求都要把Cookie添加到请求头中,服务器要从request中逐一解析Cookie,如果Cookie很多,速度会很慢。
Session是把会话信息保存在服务器上内存中,使用SessionId来唯一标识会话信息。把SessionId作为Cookie保存到浏览器上,浏览器访问页面时,会自动把该网站的SessionID这个Cookie添加到请求头中,随HTTP请求发送给服务器。服务器根据SessionId调取相应的Session,获取会话信息。
2、超时管理
当浏览器第一次访问该网站时,该网站的服务器上会创建一个Session对象来存储会话信息。
但服务器不知道浏览器会不会还会再次访问服务器,这个Session还要不要保留。如果一直保留,服务器上的Session对象会越来越多,最终耗尽服务器内存。
服务器可以设置超时时间,tomcat -> conf ->web.xml -> <session-config>:
<!-- ==================== Default Session Configuration ================= -->
<!-- You can set the default session timeout (in minutes) for all newly -->
<!-- created sessions by modifying the value below. --> <session-config>
<session-timeout>30</session-timeout>
</session-config>
默认为30分钟。如果30分钟内,该Session没有被使用,(客户端没有再次访问),服务器会自动清除该Session,原来的会话信息丢失。
之后浏览器再次访问服务器时,request中有SessionId,但服务器上没有对应的Session对象,服务器会自动创建一个新的Session对象,把新的SessionId添加到响应头中,覆盖掉浏览器中原来的SessionId。
3、HttpSession的常用方法
- HttpSession request.getSession(true) //从request中获取HttpSession对象。参数是一个boolean,表示request没有获取到HTTPSession对象怎么处理,true——自动创建并返回一个HttpSession对象,false——不自动创建,直接返回null。
- HttpSession request.getSession() //从request中获取HttpSession对象,如果不存在,则自动创建并返回。一般用这个。
这2个方法的执行过程(第一个的参数为true):
从遍历request中的Cookie,找到JSESSIONID这个Cookie,获取值(SessionId),根据值获取服务器内存中相应的Session对象,并返回这个Session对象。
如果没有获取到Session对象(首次访问或Session超时已被清除),则自动创建一个新的Session对象并返回,创建新的Session对象时,会产生一个新的SessionId,服务器会自动把这个SessionId作为Cookie添加到响应头中。
- String session.getId() //获取创建新Session时产生的SessionId。
- session.setAttribute(String name, Object value) //往指定Session中存储数据
- Object session.getAttribute(String name)
- void session.removeAttribute(String name)
- void session.invalidate() //强制使此Session对象失效,会删除此Session对象。除了等超时管理的时间到使Session失效,还可以用此方法使Session立刻失效。
4、使用示例
HttpSession session = request.getSession();
session.setAttribute("name","张三");
如果request中没有SessionId,或者request中有SessionId,但服务器内存中没有对应的Session(Session超时被清除),那么服务器会自动创建Session,并会自动创建 Cookie cookie=new Cookie("JSESSIONID",session.getId()) 这个Cookie,把这个cookie添加到响应头传回给浏览器,保存到客户端计算机上。
有一个问题:这个Cookie没有显式设置有效期,默认本次会话结束时Cookie失效。如果中途把浏览器关了,没到超时时间(Tomcat默认为30min),服务器上Session仍在,但保存SessionId的Cookie已经失效了,服务器从request中读取不到SessionId,也就找不到对应的Session。就是说如果中途关闭浏览器,会话信息会丢失。
解决方式:显式设置Cookie的有效期。
HttpSession session = request.getSession();
Cookie cookie=new Cookie("JSESSIONID",session.getId()); //name要用JSESSIONID,J表示Java
cookie.setMaxAge(60*60*24*365); //显式设置SessionId的有效期
response.addCookie(cookie); //此句代码尽量靠前(早点添加到响应消息头中)
PrintWriter writer = response.getWriter();
这样,访客中途关掉浏览器,再次打开浏览器进行访问时,会话信息依然在。
HttpSession session = request.getSession();
String name =(String) session.getAttribute("name"); //返回值是Object
Servlet Cookie、Session的更多相关文章
- JavaWeb学习之转发和重定向、会话技术:cookie、session、验证码实例、URLConnection使用(下载网页)(4)
1.转发和重定向 HttpServletResponse response 转发: RequestDispatcher dispatcher = request.getRequestDispatche ...
- cookie、session和java过滤器
基础知识理解: cookie.session和过滤器通常都是用在web应用中,cookie和session用来保存一定的数据,过滤器Filter则是在浏览器发出请求之后,而后台执行特定的请求之前发生一 ...
- Cookie、Session、jsp、EL、JSTL
会话技术 Cookie Session 从访问一个站点,到关闭不继续访问 称为一次会话过程.会话技术就是记录本次会话中客户端的状态与数据的. 会话技术分为cookie.session. cooki ...
- 【python】-- Django 分页 、cookie、Session、CSRF
Django 分页 .cookie.Session.CSRF 一.分页 分页功能在每个网站都是必要的,下面主要介绍两种分页方式: 1.Django内置分页 from django.shortcuts ...
- cookie、session和application都是些什么神?——图文加案例,不怕你不会,就怕你不看
cookie.session和application都是些什么神? 前言: 一直想写一篇关于cookie和session的博客,由于种种原因,一直没有整理,这不,今天还就遇到问题了,之前虽然会,但是好 ...
- 关于新手必须要理解的几个名词,cookie、session和token
以下要说的,虽然不是开发过程中必须会遇到的,但却是进阶之路上必须要掌握的,一些涉及到状态管理与安全的应用当中尤为重要. 我之前虽略有学习,但也是东拼西凑临时看的一点皮毛,所以在这个假期利用一点时间,整 ...
- 一文彻底搞懂Cookie、Session、Token到底是什么
> 笔者文笔功力尚浅,如有不妥,请慷慨指出,必定感激不尽 Cookie 洛:大爷,楼上322住的是马冬梅家吧? 大爷:马都什么? 夏洛:马冬梅. 大爷:什么都没啊? 夏洛:马冬梅啊. 大爷:马什 ...
- cookie 、session、JSESSIONID
cookie .session ? 让我们用几个例子来描述一下cookie和session机制之间的区别与联系.笔者曾经常去的一家咖啡店有喝5杯咖啡免费赠一杯咖啡的优惠,然而一次性消费5杯咖啡的机会微 ...
- [转]cookie、session、sessionid 与jsessionid
cookie.session.sessionid 与jsessionid,要想明白他们之间的关系,下面来看个有趣的场景来帮你理解. 我们都知道银行,银行的收柜台每天要接待客户存款/取款业务,可以有几种 ...
随机推荐
- 算法学习笔记,几个简单的Demo
算法初学的一些心得 前言:现在工作也快一年多了,有时间下班回家会学学算法,陆陆续续也接触了一些 貌似我知道的就冒泡排序其他的都不是很了解 最近买了一本书,边学边记录吧! 一些常用的方法 暴力破解 下面 ...
- 洛谷:P2952 [USACO09OPEN]牛线Cow Line:题解
题目链接:https://www.luogu.org/problemnew/show/P2952 分析: 这道题非常适合练习deque双端队列,~~既然是是练习的板子题了,建议大家还是练练deque, ...
- VUE v-for循环中每个item节点动态绑定不同函数方法
一. 业务场景: 一个title 处 可能有 一个或多个按钮, 按钮对应不同的响应事件 二. 思路 : 按钮个数 根据传入的数据length 来循环渲染, 每条数据对应的事件名称 通过动态绑定 三 ...
- android实现倒计时,最简单实现RecyclerView倒计时+SwipeRefreshLayout下拉刷新
先上效果图: RecyclerView + SwipeRefreshLayout 实现倒计时效果 MainActivity.java package top.wintp.counttimedemo1; ...
- Oculus Rift 没有声音的解决方法
If you do not hear any audio when using Rift, please try the following steps: Check the Rift audio s ...
- mysql8.0的连接写法
由于mysql8.0的新特新,所以Driver要写成“com.mysql.cj.jdbc.Driver” url:"jdbc:mysql://host_address:3306/db_nam ...
- PointCloud及其经典论文介绍
这篇博客会介绍点云的基本知识,重点介绍最近两年发表的部分经典论文,有什么建议欢迎留言! 点云基本介绍 点云是某个坐标系下的点的数据集,包含了丰富的信息,可以是三维坐标X,Y,Z.颜色.强度值.时间等等 ...
- SpringBoot日志相关
SpringBoot使用的是SLF4j当门面,Logback当实现完成 日志级别 数字越大,级别越高,框架只会输出大于等于当前日志级别的信息 ERROR 40 WARN 30 INFO 20 DEBU ...
- java反射原理及Class应用
反射:框架设计灵魂 框架:半成品软件,可以在框架基础上进行软件开发,简化编码 反射:将类的各个组成部分封装我其他对象,这就是反射机制 好处: 1.可以在程序运行过程中,操作这些对象 2.可以解耦, ...
- 使用钉钉对接禅道的bug系统,实现禅道提的bug实时在钉钉提醒并艾特对应的开发人员处理
现在公司测试中有一个痛点是每次测试人员提完bug后,需要定期去提醒开发人员查看禅道的bug记录及修复bug. 导致测试人员在项目测试中不仅要测试整个软件,还要负起实时监督提醒功能的“保姆角色”,身心疲 ...