在了解cookie和session之前,我们需要知道http请求是无状态的,那什么叫无状态呢?简单来说,无论是谁发起的请求,对于服务器来说,都一视同仁,服务器不会知道哪个请求是谁发送的,哪几个请求是有关联的。
那么,如果我想针对每客户端发起的请求各自保留一些数据,这时候该怎么办呢?这时候就需要用到cookie和session。
Cookie的特性:
Cookie具有不可跨域性,浏览器访问百度只会携带百度的cookie,访问谷歌只会携带谷歌的cookie,www.baidu.com
无法访问谷歌的cookie。而且,images.google.com
与www.google.com
虽然同属于google,但是由于域名不一样,也无法访问各自的cookie,如果希望实现两个网站的cookie共享,可以通过cookie.setDomain(".google.com")
进行设置(必须以点(.)开头),但是这种设置还是无法在a.b.google.com
中共享cookie。
在代码中,cookie也不提供修改和删除功能,只能是将cookie覆盖,假如我们想删除一个cookie,只要设置一个key同名的cookie,将maxAge设置为0,并将其添加到response中即可。值得注意的是:新建的Cookie除value、maxAge之外的所有属性,例如name、path、domain等,都要与原Cookie完全一样,否则浏览器会认为这是两个不同的cookie。
Cookie cookie=new Cookie("key","value");
cookie.setMaxAge(0);
response.addCookie(cookie);
同一个域名下默认会共享所有的cookie,那假如我们的域名www.foo.com
下有两个应用www.foo.com/web
和www.foo.com/app
,我们不希望app
应用的cookie传输到web
应用上,那么可以在app
应用中设置通过cookie.setPath("/app")
进行设置(注意必须以斜杠(/)开头),这样的话该cookie只会在contextPath为/app
的应用下传输。
关于保存中文,Cookie中保存中文只能编码。一般使用UTF-8编码即可!
Cookie部分属性说明
属性 | 说明 |
---|---|
int maxAge | Cookie失效的时间,单位秒。如果为正数,则该Cookie在maxAge秒之后失效。如果为负数,该Cookie为临时Cookie,关闭浏览器即失效。如果为0,表示删除该Cookie。默认为–1 |
boolean secure | 表明该cookie是否使用安全协议传输,如HTTPS,SSL等,默认为false |
String path | 设置cookie只在指定的目录下及其子目录下生效,类似于设置contextPath |
String domain | 设置指定域名的下级域名都能访问该cookie,必须以点(.)开始 |
String comment | 浏览器显示Cookie信息的时候显示该说明 |
session的特性:
session是保存在服务器内存中的,每个客户端都会拥有独自的session,当请求过多时,可能会导致内存溢出,所以session保存的信息尽量精简,一般用于保存用户的登录信息。
session需要根据名为jsessionid的cookie来判别请求是否来自同一个客户端:当一个客户端A的请求在服务器生成session时(例如通过request.getSession()
),服务器会生成一个唯一的id,这个id会封装成一个cookie对象(key为jsessionid,value为id),并由response.setCookie()
保存到客户端A中,客户端A下次请求服务器的时候,会将该cookie一并发送到服务器中,服务器就可以通过jsesssionid得到对应的session,由此来鉴定该请求是来自A客户端的而不是其他的客户端。
假如浏览器/客户端禁用cookie,那么一般情况下将拿不到jsessionid,服务器也就认为是一个新的连接,这时候session机制将会失效,如果希望在禁用cookie的情况下使用session,可以使用URL重写的方式去实现。
String encodeURL=response.encodeURL(url);
String encodeRedirectURL=response.encodeRedirectURL(url);
假如你请求的url是/foo
,那么重写后的URL类似/foo;jsessionid=0F8D97B0BE608AFDC3E.....
服务器就会根据jsessionid找到对应的session信息。
问题一:怎么获取cookie和session
//获取cookie
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
System.out.println(cookie.getName() + ":" + cookie.getValue());
}
//获取session,两种方式
HttpSession session = request.getSession();//相当于request.getSession(true)
HttpSession session2 = request.getSession(true);
getSession方法中参数为true,无论如何都能获取到HttpSession
对象,但是如果为false,只能获取到原有的HttpSession
对象,如果没有则返回null。
问题二:cookie和session的区别都有哪些
a. 存储位置:
cookie存储在浏览器,session是存储在服务器
b. 存储能力
单个cookie只能保存4KB的信息(这个我没有去考究),而session的保存能力跟服务器有关,能存储较大的数据量,存储的量越大对服务器越有压力。
c.失效时间
cookie默认在浏览器关闭的时候失效,可以通过setMaxAge
设置生命周期时长(单位:秒),超时后cookie会自动失效。
session失效的方式有三种:
1.超时。和cookie不同的是,每次使用session的时候会重新计算超时时间。
2.调用session.invalidate();
3.服务器崩溃或者停止
问题三、如何设置超时时间
1、session:
<!--在web.xml设置,这里设置的单位是分钟-->
<session-config>
<session-timeout>15</session-timeout>
</session-config>
//在代码中设置,这里的单位是秒
session.setMaxInactiveInterval(15*60);
2、cookie
cookie.setMaxAge(10);//单位为秒,默认是-1(关闭浏览器则清除该cookie)