Web时代-Session和Cookie(session和cookies)
wxin55 2024-11-01 14:29 9 浏览 0 评论
今天我们继续回顾以往的知识点,今天我们将重新的认识关于会话技术的知识。
浏览器开始访问网站到访问网站结束期间产生的多次请求响应组合在一起叫做一次会话,会议话的过程中会产生会话相关的数据,我们需要将这些数据保存起来。
Cookie
Cookie是客户端的技术,程序把每个用户的数据以cookie的形式写给用户的各自的浏览器,当用户使用浏览器再去访问服务器中的web资源时,这样,web资源处理的就是用户各自的数据了。
Cookie是基于set-Cookie响应头和Cookie请求头工作的,服务器可以发送set-Cookie请求头命令浏览器保存一个cookie信息,浏览器会在访问服务器时以Cookie请求头的方式带回之前保存的信息cookie在浏览器中的存放只允许存300个cookie,每个站点最多有20个cookie在浏览器的存放cookie是不安全的,很有很能被丢失;
删除cookie必须设置maxAge path 一致性才可以覆盖
cookie是客户端技术
- 数据保存在客户端,这个信息可以保存很长时间
- 数据随时有可能被清空,所以cookie保存的数据是不太靠谱的
- 数据被保存在了客户端,随时有可能被人看走,如果将一些敏感信息比如用户名密码等信息存在cookie中,可能有安全问题
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setContentType("text/html;charset=utf-8");
//创建cookie数组
Cookie[] cookies=request.getCookies();
Cookie findC=null;
if(cookies!=null){
for(Cookie c :cookies){
if("lasttime".equals(c.getName())){
findC=c;
}
}
}
if(findC==null){
response.getWriter().write("你是第一次访问这个网站");
}else{
//cookies是返回一个long行的值
Long lastTime=Long.parseLong(findC.getValue());
response.getWriter().write("你上次访问的时间是:"+new Date(lastTime).toLocaleString());
}
Date date=new Date();
Cookie cookie=new Cookie("lasttime", date.getTime()+"");
//设置cookies保存的最多时间
//相当于response中添加了一个Set-cookie的响应头
cookie.setMaxAge(36000);
//设置整个web应用的cookie信息都可以带过去;
cookie.setPath(request.getContextPath());
response.addCookie(cookie);
}
setMaxAge与getMaxAge方法
- 一个Cookie如果没有设置过MaxAge则这个Cookie是一个会话级别的Cookie,这个Cookie信息发给浏览器后浏览器会将它保存在浏览器的内存中,这意味着只要浏览器已关闭随着浏览器内存的销毁Cookie信息也就消失了.
- 一个Cookie也可以设置MaxAge,浏览器一旦发现收到的Cookie被设置了MaxAge,则会将这个Cookie信息以文件的形式保存在浏览器的临时文件夹中,保存到指定的时间到来为止.这样一来即使多次开关浏览器,由于这些浏览器都能在临时文件夹中看到cookie文件,所以在cookie失效之前cookie信息都存在.
- 想要命令浏览器删除一个Cookie,发送一个同名同path的cookie,maxage设置为0,浏览器以名字+path识别cookie,发现同名同path,cookie覆盖后立即超时被删除,从而就删除了cookie.就是一个覆盖.
setPath与getPath方法
用来通知浏览器在访问服务器中的哪个路径及其子路径时带着当前cookie信息过来如果不明确设置,则默认的路径是发送Cookie的Servlet所在的路径.
setDomain与getDomain方法
用来通知浏览器在访问哪个域名的时候带着当前的cookie信息.但是要注意,现代的浏览器一旦发现cookie设置过domain信息则会拒绝接受这个Cookie.我们平常不要设置这个方法.
Cookie是不可跨域名的。域名www.google.com颁发的Cookie不会被提交到域名www.baidu.com去。这是由Cookie的隐私安全机制决定的。隐私安全机制能够禁止网站非法获取其他网站的Cookie。
正常情况下,同一个一级域名下的两个二级域名如www.baidu.com和www.images.baidu.com也不能交互使用Cookie,因为二者的域名并不严格相同。如果想所有www.baidu.com名下的二级域名都可以使用该Cookie,需要设置Cookie的domain参数
Cookie cookie = new Cookie("time","20080808"); // 新建Cookie
cookie.setDomain("www.baidu.com"); // 设置域名
cookie.setPath("/"); // 设置路径
cookie.setMaxAge(Integer.MAX_VALUE); // 设置有效期
response.addCookie(cookie);
/**
* 显示之前看的书从cookie中获取信息
**/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setContentType("text/html;charset=utf-8");
//查询数据库中的书的展示:
Map<String, Book> map=BookDao.getbooks();
for (Map.Entry<String, Book>entry :map.entrySet()) {
Book book =entry.getValue();
response.getWriter().write("<a href='"+request.getContextPath()+"/BookInfoServlet?id="+book.getId()+"'>"+book.getName()+"</a><br>");
}
response.getWriter().write("<hr>");
//2`显示之前看过的书
Cookie[] cookies=request.getCookies();
Cookie findC=null;
if(cookies!=null){
for(Cookie c :cookies){
if("last".equals(c.getName())){
findC=c;
}
}
}
if(findC==null){
response.getWriter().write("你未浏览过");
}else{
response.getWriter().write("你浏览过书有:"+"<br/>");
//cookies是返回一个long行的值
String[] ids=findC.getValue().split(",");
for(String id :ids){
Book book=BookDao.getbook(id);
//response.getWriter().write(book.getName()+"<br/>");
}
}
}
Session
由于HTTP协议是无状态的协议,所以服务端需要记录用户的状态时,就需要用某种机制来识具体的用户,这个机制就是Session.典型的场景比如购物车,当你点击下单按钮时,由于HTTP协议无状态,所以并不知道是哪个用户操作的,所以服务端要为特定的用户创建了特定的Session,用用于标识这个用户,并且跟踪用户,这样才知道购物车里面有几本书。这个Session是保存在服务端的,有一个唯一标识。
session是服务器端技术,数据保存在服务区端,相对来说比较稳定和安全,占用服务器内存,所以一般存活的时间不会太长,超过超时时间就会被销毁.我们要根据服务器的压力和session 的使用情况合理设置session的超时时间,既能保证session的存活时间够用,同时不用的session可以及时销毁减少对服务器内存的占用.
作用范围:
当前会话范围
生命周期:
当程序第一次调用到request.getSession()方法时说明客户端明确的需要用到session此时创建出对应客户端的Session对象.
当session超过30分钟(这个时间是可以在web.xml文件中进行修改的)没有人使用则认为session超时销毁这个session.
程序中明确的调用session.invalidate()方法可以立即杀死session.
当服务器被非正常关闭时,随着虚拟机的死亡而死亡.如果服务器是正常关闭,还未超时的session会被以文件的形式保存在服务器的work目录下,这个过程叫做session的钝化.下次再正常启动服务器时,钝化着的session会被恢复到内存中,这个过程叫做session的活化.
作用:在会话范围内共享数据
session时间的配置:在配置的时是以分钟为单位的;
在web.xml中用配置<session-config><session-timeout>30</></>
session 的原理:
request.getSession()方法会检查请求中有没有JSESSIONID 如果没有则检查请求的URL后有没有以参数的形式带着JSESSIONID过来,如果有则找到对应的Session, 服务器如果找不到则认为这个浏览器没有对应的Session,创建一个Session然后再在响应中添加JSESSIONID
cookie的值就是这个Session 的id
默认情况下,JSESSIONID 的path为当前web应用的名称,并且没有设置过MaxAge,是一个会话级别的cookie.
这意味着一旦关闭浏览器再新开浏览器时,由于JSESSIONID丢失,会找不到之前的Session我们可以手动的发送JSESSIONID cookie,名字和path设置的和自动发送时一样,但是设置一下MaxAge,使浏览器除了在内存中保存JSESSIONID信息以外还在临时文件夹中以文件的形式保存,这样即使重开浏览器仍然可以使用之前的session
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
String prod=request.getParameter("prod");
prod=new String(prod.getBytes("iso8859-1"),"UTF-8");
HttpSession session=request.getSession();
Cookie jc=new Cookie("JSESSIONID", session.getId());
jc.setPath(request.getContextPath());
jc.setMaxAge(1800);
response.addCookie(jc);
session.setAttribute("prod", prod);
}
/**
*
*登录后将用户信息存到session中
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//1.获取用户名密码
String username = request.getParameter("username");
String password = request.getParameter("password");
//2.查询数据库检查用户名密码
if(UserDao.valiNamePsw(username, password)){
//3.如果正确登录后重定向到主页
request.getSession().setAttribute("user", username);
response.sendRedirect(request.getContextPath()+"/loginout/index.jsp");
return;
}else{
//4.如果错误提示
response.getWriter().write("用户名密码不正确!");
}
}
/**
* 退出时把session杀死
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//1.杀死session
//request.getsession();如果没有session会创建一个
if(request.getSession(false)!=null
&& request.getSession().getAttribute("user")!=null){
request.getSession().invalidate();
}
//2.重定向到主页
response.sendRedirect(request.getContextPath()+"/loginout/index.jsp");
}
/**
* 防止form表单重复提交
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
request.setCharacterEncoding("utf-8");
try {
Thread.sleep(4*1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String username = request.getParameter("username");
String valinum = request.getParameter("valinum");
String valinum2 = (String) request.getSession().getAttribute("valinum");
if(valinum2!=null && !"".equals(valinum2) && valinum.equals(valinum2)){
request.getSession().removeAttribute("valinum");
System.out.println("向数据库中注册一次:"+username);
}else{
response.getWriter().write("from web:不要重复提交!!");
}
}
URL重写:
如果浏览器禁用了Cookie,浏览器就没有办法JSESSIONID cookie,这样就用不了Session了.我们可以使用URL重写的机制,在所有的超链接后都以参数的形式拼接JSESSIONID信息,从而在点击超链接时可以使用URL参数的方式带回JSESSIONID,从而使用Session将URL进行重写拼接上JSESSIONID的过程就叫做URL重写
request.getSession() --在URL重写之前一定要先创建出Session,才有Session id,才能进行重写
response.encodeURL()--- 一般的地址都用这个方法重写
response.encodeRedirectURL() --- 如果地址是用来进行重定向的则使用这个方法
url重写的方法一旦发现浏览器带回了任意cookie信息,则认为客户端没有禁用cookie,就不会再进行重写操作
以上就是本文分享的内容,如果喜欢请点个再看。
相关推荐
- Java中List 和 Map、Set 的区别(list和set和map)
-
hello,大家好,我是霖仔java集合的大家了解,我再给大家说一下他们的区别,希望能够帮助到大家结构特点:List和Set是存储单列数据的集合,Map是存储键和值这样的双列数据的集合;Lis...
- Java 集合框架全面解析:选对数据结构,提升开发效率
-
上一章我们详细介绍了各种常用的数据结构情况(参考:数据结构复杂度全览:如何选择最优结构?),本文结合关键数据结构,从列表(List)、队列(Queue)、集合(Set)、映射(Map)四个维度,深入解...
- LinkedList竟然比ArrayList慢了1000多倍?(动图+性能评测)
-
数组和链表是程序中常用的两种数据结构,也是面试中常考的面试题之一。然而对于很多人来说,只是模糊的记得二者的区别,可能还记得不一定对,并且每次到了面试的时候,都得把这些的概念拿出来背一遍才行,未免有些麻...
- LinkedList 底层源码深度解析(linkedlist底层数据结构)
-
目录1.引言2.LinkedList概述2.1类继承体系图2.2各个接口作用3.与ArrayList的对比4.底层数据结构5.核心方法源码解析5.1add()方法5.2a...
- List的用法和实例详解——Java进阶知识讲义系列(四)
-
序欢迎来到全网最完整的Java进阶知识系列教程!!!每天定时更新!!!本期是Java进阶知识系列的第四讲,将分享Java常用的数据容器——集合类。集合类也分很多类型,比如:List、Set、Map、Q...
- Rust高效集合操作(rust基本操作)
-
集合的分类Rust的集合类型主要分布在标准库的std::collections模块中,同时也包括语言内置的数组和字符串类型序列容器序列容器维护元素的顺序,适合需要按索引访问或顺序遍历的场景向量(...
- Java八股文:核心知识点梳理(java八股文是啥)
-
一、Java基础1.Java基本数据类型8种基本类型:整型:byte(1),short(2),int(4),long(8)浮点型:float(4),double(8)字符型:char(2)布...
- 为什么我不推荐研发人员使用 LinkedList?
-
在Java集合框架中,LinkedList作为List的实现之一,经常被认为是ArrayList的替代方案。然而,在大多数实际场景下,我们并不推荐使用LinkedList,原因主要集中...
- ArrayList 、 LinkedList、Vector的区别
-
ArrayList、LinkedList、Vector的区别如下:ArrayListLinkedListVector结构动态数组双向链表动态数组是否线程安全否否是效率遍历查找快,插入删除慢插入删除...
- (2020 )Java最新面试笔试题答案解析(一)
-
Java中的集中基本数据类型是什么?各占用多少字节?【数值型】—(整数类型)byte(1字节)short(2字节)int(4字节)long(8字节)拓展:Java中的数据类型除了上面的基本...
- 超简单五步实现Linux虚拟机CentOS 7系统Root密码忘记重置
-
环境:CentOS7.5重置root密码:1.CentOS7虚拟机开机,将鼠标光标移动至虚拟机内。2.在虚拟机中使用键盘上↑和↓键将选择行设置为第一行(背景高亮即为选中),按下键盘上的e,进...
- 吊轨门和推拉门哪个好?北京今朝区别介绍看完不入坑
-
厨房到底使用什么门好?相信这是大多数业主都比较抓狂的事情,其实在装修中材料的选择最终还是要依据空间而定,那么吊轨门和推拉门哪个好呢?下面就跟随北京装修网一起来看看吧!吊轨门与推拉门介绍吊轨门吊轨门的特...
- 〖省钱宝典〗不花冤枉钱,少走弯路!居家中推拉门如何设计?
-
想要空间最大程度的显大?想要充足的光线?又想拥有合理的区域划分?那么推拉门是你绝对不能错过的好选择。推拉门的设计轻盈简洁,绝对是室内每个空间的福音。它不仅可以最大化地节省空间,方便了居室的功能划分和利...
- 吊趟门与推拉门有什么区别?(吊趟门贵还是推拉门贵)
-
吊趟门与推拉门的区别很多人在购买的时候并不清楚,有些客人甚至根本分不清吊趟门和推拉门,今天小编就给大家讲讲吊趟门与推拉门的相关内容,看看吊趟门与推拉门的区别有哪些?1、推拉门采用以门扇下滑轮为主支撑点...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- Java中List 和 Map、Set 的区别(list和set和map)
- Java 集合框架全面解析:选对数据结构,提升开发效率
- LinkedList竟然比ArrayList慢了1000多倍?(动图+性能评测)
- LinkedList 底层源码深度解析(linkedlist底层数据结构)
- List的用法和实例详解——Java进阶知识讲义系列(四)
- Rust高效集合操作(rust基本操作)
- Java八股文:核心知识点梳理(java八股文是啥)
- 面试题:ArrayList和LinkedList有什么区别?
- 为什么我不推荐研发人员使用 LinkedList?
- ArrayList 、 LinkedList、Vector的区别
- 标签列表
-
- hive行转列函数 (63)
- sourcemap文件是什么 (54)
- display none 隐藏后怎么显示 (56)
- 共享锁和排他锁的区别 (51)
- httpservletrequest 获取参数 (64)
- jstl包 (64)
- qsharedmemory (50)
- watch computed (53)
- java中switch (68)
- date.now (55)
- git-bash (56)
- 盒子垂直居中 (68)
- npm是什么命令 (62)
- python中+=代表什么 (70)
- fsimage (51)
- nginx break (61)
- mysql分区表的优缺点 (53)
- centos7切换到图形界面 (55)
- 前端深拷贝 (62)
- kmp模式匹配算法 (57)
- jsjson字符串转json对象 (53)
- jdbc connection (61)
- javascript字符串转换为数字 (54)
- mybatis 使用 (73)
- 安装mysql数据库 (55)