Java中Cookie和Session的那些事儿
作者:luoxn28 发布时间:2022-09-24 08:24:54
Cookie和Session都是为了保持用户的访问状态,一方面为了方便业务实现,另一方面为了简化服务端的程序设计,提高访问性能。Cookie是客户端(也就是浏览器端)的技术,设置了Cookie之后,每次访问服务端,请求中都会带上Cookie;Session是服务端技术,在服务端存储用户的访问信息。
使用Cookie传递信息,随着Cookie个数增多和访问量增大,它占用的带宽会越来越大;使用Session保存信息,最大的弱点就是不容易在多台服务器之间共享。
1 Cookie
通俗地讲,当用户使用HTTP访问服务器时,服务器会将一些键值对信息返回给客户端浏览器,并且给这些数据加一些限制条件,在符合限制条件情况下用户下次访问服务器时,会带上之前设置的Cookie键值对信息。当该用户输入 URL 时,浏览器便会在本地硬盘上查找与该 URL 关联的 Cookie。如果该 Cookie 存在,浏览器便将该 Cookie 与页请求一起发送到您的站点。
Cookie 与网站关联,而不是与特定的页面关联。因此,无论用户请求站点中的哪一个页面,浏览器和服务器都将交换 Cookie 信息。用户访问不同站点时,各个站点都可能会向用户的浏览器发送一个 Cookie;浏览器会分别存储所有 Cookie。
Cookie属性项
当前Cookie有2个版本,Version 0 和 Version 1,它们有2种设置响应头标识,分别是"Set-Cookie"和"Set-Cookie2"。
Cookie 0属性值
Cookie 1属性值
Java中使用Cookie示例
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
Cookie[] cookies = request.getCookies();
String name = getCoodie(cookies, "name");
if (name == null) {
response.addCookie(new Cookie("name", "luoxn28"));
}
else {
System.out.println(name);
}
out.println("hello world");
}
public static String getCoodie(Cookie[] cookies, String key) {
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals(key)) {
return cookie.getValue();
}
}
}
return null;
}
使用Cookie的一些注意事项(以Java使用为例)
•所创建的Cookie的name和value不能为非ASSIC字符,如果是中文,可以通过RRLEncoder将其编码,否则会抛出java.lang.IllegalArgumentException异常。
•多出现多个name和value值时,它们实在同一个"Cookie"头中的。
•Cookies的值中可以保存除了“;”以外的标点符号。但是不能保存汉字。保存汉字会出现乱码。
Cookie的一些限制
Cookie是HTTP头中的一个字段,HTTP本身对该字段没有限制,但是Cookie最终存储在浏览器中,不同的浏览器对Cookie的存储有一些限制,如下表所示:
如果试图存储更多 Cookie,则最旧的 Cookie 便会被丢弃。
2 Session
Session解决了Cookie增多时会增加客户端与服务器的数据传输量问题,同一个客户端与服务器交互时,不需要每次都传回所有的Cookie值,而是只要传回一个ID值,这个ID是客户端第一次访问服务器时生成的,而且每个客户端是唯一的,这个ID通常是name为JSESSIONID的一个Cookie。
Session是如何基于Cookie工作的呢,可以是基于URL Path Parameter方式;也可以是基于Cookie,如果没有修改Context容器中的Cookies标识,则默认也是支持的。当浏览器不支持Cookie功能时,浏览器会将用户的SessionCookieName重写到用户请求的URL参数中,它的传递方式如/path/Servlet;name=xxx;name2=xxx2?name3=xxx3。SessionCookieName如果在web.xml中配置session-config配置项,其cookie-config下的name属性就是这个SessionCookieName的值。如果没有配置session-config配置项,默认的SessionCookieNamejiushi “JSESSIONID”。注意,与Session关联的Cookie与其他Cookie并没有什么不同。如果客户端也支持Cookie,则Tomcat仍会解析Cookie中的Session ID,并会覆盖URL中的Session ID。
Session如何工作
有了Session ID,服务器就可以创建HttpSession对象了,第一次调用request.getSession()方法,如果没有对应的HttpSession对象,则会创建一个新的,并将这个对象加入到org.apache.catalina.Manager的sessions容器中保存。Manage保存所有的session生命周期,Session过期被回收,服务器关闭,Session被序列化到磁盘。注意,一个客户端对应一个Session对象,这个对象正是保存我们创建的Session值的。
request.getSession()方法调用的StandardSession永远都会存在,即使与这个客户端关联的Session已经过期。如果过期,则会创建一个新的,但是以前设置的Session值将会丢失。
3 Cookie与Session安全性比较
Cookie将保存的数据通过HTTP头部从客户端传到服务端,从服务端再传回到客户端,所有的数据都保存在客户端浏览器中,这些数据都是可以访问到的,甚至可以通过插件添加、修改Cookie,所有Cookie的安全性是比较差的。相比较而言,Session将数据保存在服务器端,安全性高很多,只需要Cookie传回一个Cookie ID就可以,所以Session更适合保存用户隐私和重要的数据。
分布式Session框架
在大型互联网应用中,单用Cookie和Session都是不可行的,因为如果使用Cookie可以很好地解决应用的分布式部署问题,大型互联网应用系统一个应用有上百台机器,而且有很多不同的应用系统协同工作,由于Cookie是将数据存储在用户浏览器中,用户每次访问都会讲数据带回到服务器,也就解决了同一个用户的请求在不同服务器上处理而导致的Cookie不一致问题。
由于应用是一个集群,所以不能将Session都保存在每台服务器的内存中,如果每台服务器有几十万访问用户,服务器内存也容不下,即使容得下,也无法保证该Session同步到其他服务器中,所以共享这些Session需要将它们保存在专门的分布式缓存中,可以随时读取和写入,性能要够好满足要求,如memcache/redis或者淘宝的开源分布式框架Tair都是很好的选择。
表单重复提交问题
网站中有很多地方有重复提交表单问题,为了防止表单重复提交,就要标识用户的每一次访问请求,使得每一次访问请求对服务端来说都是唯一的,为了标识用户的每次请求,可以在用户请求的表单域增加一个隐藏表单项,其值为唯一的token,如:
<form id="form" method="post">
...
<input type=hidden name="token" value="xxx"/>
</form>
用户请求表单时生成唯一的token,并且设置到该用户的Session中,等用户提交时检测这个token是否和Session中保存的token一致,如果一致,说明没有重复提交,同时把Session中的token更新成一个新的token值;否则用户提交上来的token已经不是当前请求的合法token,提交失败。
以上所述是小编给大家介绍的Java中Cookie和Session的那些事儿网站的支持!
来源:http://www.cnblogs.com/luoxn28/p/5894557.html


猜你喜欢
- mongodb的数据插入速度是其一个亮点,同样的10000条数据,插入的速度要比Mysql和sqlserver都要快,当然这也是要看使用者怎
- Activiti项目是一项新的基于Apache许可的开源BPM平台,本文就来简述一下Activiti常用类。具体如下:一、为什么要使用工作流
- 跟同事讨论到- 用C# Stopwatch 取得效能数值,Stopwatch.ElapsedMilliseconds 只到毫秒(ms),如果
- 最近的一个接口项目,传的参数要求是json,需要特殊处理一下。重点是这两句话:httpPost.setHeader("Conten
- 1.属性驱动 前台表单中字段的name和后台action中的属性字段的名称必须保持一致;2.域驱动 前台表单中字段的name应该为:obje
- 在使用java项目时,如果没有详细的管理和辅助流程,就会像程序失去了系统的调配一样。在java中有一种专门管理项目的工具,叫做maven,除
- using System;using System.Collections.Generic;using System.ComponentMo
- 做tcp网络编程,要解析一批批的数据,可是数据是通过Socket连接的InputStream一次次读取的,读取到的不是需要转换的对象,而是要
- Java8对集合提供了一种流式计算的方式,这种风格将要处理的元素集合看 作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如
- 1.首先看下我的项目结构我们逐个讲解/** * 用户登录配置类 * @author Administrator * */public cla
- 这篇文章主要介绍了dotnet core链接mongodb代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价
- 前段时间在项目开发中,有listview实现单选和多选的效果,特别是listview的单选效果,一开始项目比较紧,自己考虑的是用listvi
- 目录Web服务器技术讲解PHP:JSP/ServletWeb服务器IISTomcatJAVA jdk中的内容TomcatTomcat根目录下
- Main方法如下:static void Main(string[] args){ dynamic st
- 文章来源:csdn 作者:wangfengsdu经常听到回调函数(callback function)这个概念, 所谓回调函数,就是指这个函
- JDK12的五大重要新特性Java12在March 19, 2019发布了。在2017年发布Java 9之后,Java平台发布节奏已从每3年
- 我们经常需要对我们的开发的软件做各种测试, 软件对系统资源的使用情况更是不可少, 目前有多个监控工具, 相比JProfiler对系统资源尤其
- 1.简介本教程将介绍如何在Spring Security中设置身份验证提供程序,与使用简单UserDetailsService的标准方案相比
- 众所周知,android里面我们很熟悉的一个功能,侧滑菜单效果在以前我们大部分都是用的slidingmenu这个开源框架,自从谷歌官方新出的
- 本文介绍了springcloud Feign的Hystrix支持,分享给大家,具体如下:一、Feign client中加入Hystrix的f