Cookie和Session

Cookie

是由服务器给客户端,并且存储在客户端上的一份小数据

Cookie的作用

  http的请求是无状态的。客户端与服务器在通讯的时候,是无状态的,客户端第二次来访的时候,服务器根本就不知道这个客户端之前有没有访问过。使用Cookie,可以获得更好的交互(自动登陆),从公司层面上讲,可以更好的收集用户习惯(大数据)。在自动登陆,浏览记录以及购物车等应用场景的设计都可以使用Cookie来实现。

具体使用

添加Cookie给客户端

在响应的时候,添加cookie

Cookie cookie = new Cookie("name", "qf");
//给响应添加一个cookie
resp.addCookie(cookie); 

客户端收到的信息里面,响应头里会多一个Set-Cookie字段

获取客户端带来的cookie

Cookie[] cookies = req.getCookies();
if(cookies != null) {
  for (Cookie cookie : cookies) {
    System.out.println("cookie-name:"+cookie.getName()+", cookie-value:"+cookie.getValue());
  }
}

console输出结果

cookie-name:JSESSIONID, cookie-value:D3593AAE6FB6876291B28512670984BB
cookie-name:name, cookie-value:qf
cookie-name:Hm_lvt_416b1ab2cd19be52c35938635a3cf5c5, cookie-value:1525223695
cookie-name:Hm_lvt_4e42f3810ab58451dc11277aa62ca512, cookie-value:1525223695

Cookie常用的API方法

1.设置有效期

没有设置有效期的cookie,关闭浏览器后,cookie就没有了

cookie.setMaxAge(int expiry);

expiry: 有效期 以秒计算。

正值 : 表示 在这个数字过后,cookie将会失效

负值: 关闭浏览器,那么cookie就失效, 默认值是 -1

cookie.setMaxAge(60 * 60 * 24 * 7);//设置一周的有效期

删除cookie是没有什么delete方法的。只有设置maxAge 为0;

会话Cookie 默认情况下,关闭了浏览器,那么cookie就会消失

2.赋值新的值

cookie.setValue(newValue); 

3.用于指定只有请求了指定的域名,才会带上该cookie(跨域共享cookie)

cookie.setDomain(".baidu.com");

A机所在的域:abcd.com,A有应用webapp_a 
B机所在的域:jszx.com,B有应用webapp_b 
1)在webapp_a下面设置cookie的时候,增加cookie.setDomain(“.jszx.com”);,这样在webapp_b下面就可以取到cookie。

2)输入url访问webapp_b的时候,必须输入域名才能解析。比如说在A机器输入:http://lc-bsp.jszx.com:8080/webapp_b,可以获取webapp_a在客户端设置的cookie,而B机器访问本机的应用,输入:http://localhost:8080/webapp_b则不可以获得cookie。

3)设置了cookie.setDomain(“.jszx.com”),还可以在默认的abcd.com下面共享

4.只有访问该域名下的cookieDemo的这个路径地址才会带cookie

  cookie.setPath("/CookieDemo");

本机tomcat/webapp下面有两个应用:webapp_a和webapp_b。

原来在webapp_a下面设置的cookie,在webapp_b下面获取不到,path默认是产生cookie的应用的路径

若在webapp_a下面设置cookie的时候,增加一条cookie.setPath(“/”);或者cookie.setPath(“/webapp_b/”); 就可以在webapp_b下面获取到cas设置的cookie了。

此处的参数,是相对于应用服务器存放应用的文件夹的根目录而言的(比如tomcat下面的webapp),因此cookie.setPath(“/”);之后,可以在webapp文件夹下的所有应用共享cookie,而cookie.setPath(“/webapp_b/”); 是指cas应用设置的cookie只能在webapp_b应用下的获得,即便是产生这个cookie的webapp_a应用也不可以。

设置cookie.setPath(“/webapp_b/jsp”)或者cookie.setPath(“/webapp_b/jsp/”)的时候,只有在webapp_b/jsp下面可以获得cookie,在webapp_b下面但是在jsp文件夹外的都不能获得cookie。

设置cookie.setPath(“/webapp_b”);,是指在webapp_b下面才可以使用cookie,这样就不可以在产生cookie的应用webapp_a下面获取cookie了。

有多条cookie.setPath(“XXX”);语句的时候,起作用的以最后一条为准。

案例:显示最近访问的时间

  1. 判断账号密码是否正确

  2. 如果正确,则获取cookie。 但是得到的cookie是一个数组, 我们要从数组里面找到我们想要的对象。

  3. 如果找到的对象为空,表明是第一次登录。那么要添加cookie

  4. 如果找到的对象不为空, 表明不是第一次登录

 1 public class CookieServlet extends HttpServlet {
 2     @Override
 3     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 4         String username = req.getParameter("username");
 5         String password = req.getParameter("password");
 6         resp.setContentType("text/html;charset=UTF-8");
 7         if("admin".equals(username)&&"123".equals(password)) {
 8             System.out.println("login success");
 9             Cookie[] cookies = req.getCookies();
10             if(cookies != null) {
11                 Cookie c = null;
12                 for (Cookie cookie : cookies) {
13                     String name = cookie.getName();
14                     if("lastTime".equals(name)) {
15                         c = cookie;
16                         break;
17                     }
18                 }
19                 if(c == null) {
20                     c = new Cookie("lastTime",System.currentTimeMillis()+"");
21                     c.setMaxAge(60*60*2);
22                     resp.addCookie(c);
23                     resp.getWriter().write("欢迎你!"+username);
24                 }else {
25                     String value = c.getValue();
26                     c.setValue(System.currentTimeMillis()+"");
27                     resp.addCookie(c);
28                     resp.getWriter().write("欢迎你!"+username);
29                     resp.getWriter().write("上次访问时间:"+value);
30                 }
31             }
32         }
33     }
34 }

---------再次访问---------

由于Cookie会保存在客户端上,所以有安全隐患问题。 还有一个问题, Cookie的大小与个数有限制。 为了解决这个问题,引入 Session

Session

 会话 , Session是基于Cookie的一种会话机制。 Cookie是服务器返回一小份数据给客户端,并且存放在客户端上。 Session是,数据存放在服务器端。

会在客户端cookie里面添加一个字段 JSESSIONID . 是tomcat服务器生成的

 Session常用API方法

  1. 得到会话ID String id = session.getId();
  2. 存值 session.setAttribute(name, value);
  3. 取值 session.getAttribute(name);
  4. 移除值 session.removeAttribute(name);

创建/销毁

创建:

只有在servlet里面调用了 request.getSession(),才会创建Session对象

测试:分别请求servlet和jsp,通过浏览器查看是否生成session

结果:请求servlet没有产生session,请求jsp产生了session。

原因:

  1. jsp的本质是servlet,只有在servlet中调用request.getSession();或者request.getSession(true);服务器才会产生session。如果调用request.getSession(false);将不会产生session。
  2. jsp会生成session是因为jsp生成的源代码中会通过pageContext.getSession()自动生成session

session 是存放在服务器的内存中的一份数据;即使关了浏览器,session也不会销毁

销毁:

  1. 关闭服务器

  2. session会话时间过期。 有效期过了,默认有效期: 30分钟

    1. 项目的web.xml中设置
      <session-config>
        <session-timeout>30</session-timeout>
      </session-config>
    2. session.setMaxInactiveInterval(30*60)方法
    3. tomcat的conf/web.xml中设置
      <session-config>
        <session-timeout>30</session-timeout>
      </session-config>
  3. 调用invalidate()方法
  4. 关闭浏览器(并没有销毁session)
    • 存在于浏览器上的唯一标识符JSESSIONID(sessionid)消失了,但是服务器中存放的sessionid并没有立马销毁
    • sessionid消失导致找不到服务器端的session内容
原文地址:https://www.cnblogs.com/qf123/p/10065355.html