1.1 观点理解
要理解session和cookie是什么,先要理解以下几个观点。
1.1.1 无状态的HTTP协议
协议:是指打算机通信网络中两台打算机之间进行通信所必须共同遵守的规定或规则。
超文本传输协议(HTTP):是一种通信协议,它许可将超文本标记措辞(HTML)文档从Web做事器传送到客户真个浏览器。
HTTP协议是无状态的协议。一旦数据交流完毕,客户端与做事器真个连接就会关闭,再次交流数据须要建立新的连接。这就意味着做事器无法从连接上跟踪会话。
1.1.2 会话(Session)跟踪
会话:指用户登录网站后的一系列动作,比如浏览商品添加到购物车并购买。会话(Session)跟踪是Web程序中常用的技能,用来跟踪用户的全体会话。常用的会话跟踪技能是Session与Cookie。Session通过在做事器端记录信息确定用户身份,Cookie通过在客户端记录信息确定用户身份。
1.2 Cookie
由于HTTP是一种无状态的协议,做事器单从网络连接上无从知道客户身份。用户A购买了一件商品放入购物车内,当再次购买商品时做事器已经无法判断该购买行为是属于用户A的会话还是用户B的会话了。怎么办呢?就给客户端们颁发一个通畅证吧,每人一个,无论谁访问都必须携带自己通畅证。这样做事器就能从通畅证上确认客户身份了。这便是Cookie 的事情事理。
Cookie实际上是一小段的文本信息。客户端要求做事器,如果做事器须要记录该用户状态,就利用response向客户端浏览器颁发一个Cookie。客户端会把Cookie保存起来。
当浏览器再要求该网站时,浏览器把要求的网址连同该Cookie一同提交给做事器。做事器检讨该Cookie,以此来辨认用户状态。做事器还可以根据须要修正Cookie的内容。
1.2.1 会话Cookie和持久Cookie 若不设置过期韶光,则表示这个cookie的生命期为浏览器会话期间,关闭浏览器窗口,cookie就消逝。这种生命期为浏览器会话期的cookie被称为会话cookie。会话cookie一样平常不存储在硬盘上而是保存在内存里,当然这种行为并不是规范规定的。
若设置了过期韶光,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie仍旧有效直到超过设定的过期韶光。存储在硬盘上的cookie可以在浏览器的不同进程间共享。这种称为持久Cookie。
1.2.2 Cookie具有不可跨域名性
便是说,浏览器访问百度不会带上谷歌的cookie
1.3 Session
Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在做事器上。客户端浏览器访问做事器的时候,做事器把客户端信息以某种形式记录在做事器上,这便是Session。客户端浏览器再次访问时只须要从该Session中查找该客户的状态就可以了。每个用户访问做事器都会建立一个session并自动分配一个SessionId,用于标识用户的唯一身份。
1.3.1 两个问题
1)如何在每次要求时都把SessionId自动带到做事器呢?
那便是cookie了,如果你想为用户建立一次会话,可以在用户授权成功时返回一个唯一的cookie。当一个用户再次发起要求时,浏览器会将用户的SessionId自动附加在HTTP头信息中(这是浏览器的自动功能,用户不会察觉到,开拓职员也不需操作),当做事器处理完这个要求后,将结果返回给 SessionId 所对应的用户。
2)储存须要的信息。
做事器通过SessionId作为key,读写对应的value,这就达到了保持会话信息的目的。
1.3.2 Session的创建
当程序须要为某个客户真个要求创建一个session时,做事器首先检讨这个客户真个要求里是否已包含了sessionId,如果已包含则解释以前已经为此客户端创建过session,做事器就按照sessionId把这个session检索出来利用(检索不到,会新建一个),如果客户端要求不包含sessionId,则为此客户端创建一个session并且天生一个与此session干系
联的sessionId,sessionId的值是一个既不会重复,又不随意马虎被找到规律以仿造的字符串,这个sessionId将被在本次相应中返回给客户端保存。
1.3.3 禁用cookie
如果客户端禁用了cookie,常日有两种方法实现session而不依赖cookie。
1)URL重写。便是把sessionId直接附加在URL路径的后面。
2)表单隐蔽域。做事器会自动修正表单,添加一个隐蔽字段,以便在表单提交时能够把sessionId传回做事器。
比如:
<form name=\"大众walking-form\"大众 action=\公众/xxx/xxx\公众> <input type=\"大众hidden\"大众 name=\"大众JSessionId\公众 value=\"大众NaOw3vjFW75aKnsF2C2HmdnV9LZcEbzWoWiBdHnLerjQ99zmpQng!-142002807\公众> <input type=\"大众text\"大众> </form>复制代码
4、Session共享 对付多网站(同一父域不同子域)单做事器,我们须要办理的便是来自不同网站之间SessionId的共享。由于域名不同(aaa.walking.com 和 bbb.walking.com),而SessionId又分别储存在各自的cookie中,因此做事器会认为对付两个子站的访问,是来自不同的会话。办理的方法是通过修正cookies的域名为父域名达到cookie共享的目的,从而实现SessionId的共享(非做事器集群session共享)。带来的弊端便是,子站间的cookie信息也同时被共享了。
1.4 运用处景
登录网站,今输入用户名密码登录了,第二天再打开很多情形下就直接打开了。这个时候用到的一个机制便是cookie。 session一个场景是购物车,添加了商品之后客户端处可以知道添加了哪些商品,而做事器端如何判别呢,以是也须要存储一些信息就用到了session。
2. 怎么操作Session
在Java Web开拓中,Session为我们供应了很多方便,Session是由浏览器和做事器之间掩护的。在传统的java web开拓,我们通过实现 javax.servlet.Servlet 接口或继续 javax.servlet.http.HttpServlet 来实现客户端和做事端以Http协议交互。
2.1 操作Session的API
对Session的操作如下:
@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpSession session = request.getSession(); session.setAttribute(\"大众userName\"大众,\"大众walking\"大众);//设置属性 session.setMaxInactiveInterval(3060);//过期韶光 单位秒 session.getCreationTime();//获取session的创建韶光 session.getLastAccessedTime();//获取上次与做事器交互韶光 String id = session.getId();//获取sessionId int timeout = session.getMaxInactiveInterval();//获取session过期韶光 session.invalidate();//销毁session}复制代码
客户端与做事端对用户信息的坚持有一个韶光限定,由于客户端永劫光(休眠韶光)没有与做事器交互,该session被认为已过期,做事器将此Session销毁,客户端再一次与做事器交互时之前的Session就不存在了。这便是session的过期。
2.2 设置Session过期韶光
2.2.1 传统web项目中设置Session过期韶光
1、在web.xml中设置session-config
如下:
<session-config> <session-timeout>2</session-timeout></session-config>复制代码
即,客户端连续两次与做事器交互间隔韶光最长为2分钟,2分钟后session.getAttribute()获取的值为空。原来的session已被销毁,重新的session里获取之前设置的属性值自然就为空了。
2、在Tomcat的/conf/web.xml中
session-config,默认值为:30分钟
<session-config> <session-timeout>30</session-timeout></session-config>复制代码
3、在Servlet中设置
HttpSession session = request.getSession();session.setMaxInactiveInterval(60);//单位为秒复制代码
2.2.2 SpringBoot项目中设置Session过期韶光
2.3 解释
1.优先级:Servlet中API设置 > 程序/web.xml设置 > Tomcat/conf/web.xml设置
2.若访问做事器session超时(本次访问与上次访问韶光间隔大于session最大的不活动的间隔韶光)了,即上次会话结束,但做事器与客户端会产生一个新的会话,之前的session里的属性值全部丢失,产生新的sesssionId
3.客户端与做事器一次有效会话(session没有超时),每次访问sessionId相同,若代码中设置了session.setMaxInactiveInterval()值,那么这个session的最大不活动间隔韶光将被修正,并被运用为新值。
4.Session的销毁(代表会话周期的结束):在某个要求周期内调用了Session.invalidate()方法,此要求周期结束后,session被销毁;或者是session超时后自动销毁;或者客户端关掉浏览器
5.对付JSP,如果指定了<%@ page session=\公众false\公众%>,则在JSP中无法直接访问内置的session变量,同时也不会主动创建session,由于此时JSP未自动实行request.getSession()操作获取session。
3. 操作Cookie
3.1 做事端操作Cookie
前面说过,客户端每次要求做事器会把cookie信息放到header头信息中,我们可以通过 HttpServletRequest.getCookies()方法获取所有cookie工具,通过 HttpServletResponse 工具的addCookie方法向客户端返回cookie。
详细操作API如下:
Cookie[] cookies = request.getCookies();//request工具获取所有cookiefor (Cookie cookie : cookies) { String name = cookie.getName();//cookie name String value = cookie.getValue();//cookie value String domain = cookie.getDomain();//域名 int maxAge = cookie.getMaxAge();//过期韶光 boolean secure = cookie.getSecure();//浏览器通过安全协议发送cookies 返回true String comment = cookie.getComment();//描述 int version = cookie.getVersion();//版本 //以上除name属性都有对应set方法 boolean httpOnly = cookie.isHttpOnly();//是否Httponly cookie.setHttpOnly(true);//设置Httponly值}//new cookie工具Cookie cookie = new Cookie(\"大众userName\公众,\"大众walking\"大众);cookie.setPath(\"大众/\公众);cookie.setMaxAge(6030);//30分钟response.addCookie(cookie);//回写给客户端浏览器复制代码
3.2 前端操作cookie
前端创建设置cookie
/ 创建并设置cookie @param name cookie名称 @param value cookie值 @param expires 过期韶光 毫秒 不填则默认30分 /function Setcookie(name, value, expires) { //设置名称为name,值为value的Cookie expires = expires || 30 60 1000; var expdate = new Date(); //初始化韶光 expdate.setTime(expdate.getTime() + expires); //韶光 //即document.cookie= name+\"大众=\"大众+value+\"大众;path=/\公众; 韶光可以不要,但路径(path)必须要填写, // 由于JS的默认路径是当前页,如果不填,此cookie只在当前页面生效!
~ document.cookie = name + \"大众=\公众 + value + \"大众;expires=\公众 + expdate.toGMTString() + \"大众;path=/\公众;}复制代码
前端获取cookie属性值
/ 获取对应cookie属性的value @param c_name cookie属性name @returns {string} cookie value /function getCookie(c_name) { if (document.cookie.length > 0) { c_start = document.cookie.indexOf(c_name + \"大众=\"大众); if (c_start != -1) { c_start = c_start + c_name.length + 1; c_end = document.cookie.indexOf(\"大众;\"大众, c_start); if (c_end == -1) c_end = document.cookie.length; return unescape(document.cookie.substring(c_start, c_end)); } } return \"大众\公众;}复制代码
4. 总结
1、cookie数据存放在客户的浏览器上,session数据放在做事器上。
2、cookie不是很安全,别人可以剖析存放在本地的cookie并进行cookie欺骗,考虑到安全应该利用session。
3、session会在一定韶光内保存在做事器上。当访问增多,会比较占用你做事器的性能,考虑到减轻做事器性能方面,应该利用cookie。
4、单个cookie保存的数据不能超过4K,很多浏览器都限定一个站点最多保存20个cookie。
5、可以考虑将登录信息等主要信息存放为session,其他信息如果须要保留,可以放在cookie中。
6、在程序开拓过程中,我们可以在客户端每次与做事器交互时检讨SessionID(Session中属性值,非HttpServlet环境开拓中也可以用其它的Key值代替),用于会话管理。
关注私信回答:555领取Java高等架构资料、Spring源码剖析、Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式等