cookie 和 httpSession

目录

1.认识Cookie对象与HttpSession

1.1概念

1.2会话管理

2.cookie的使用

2.1cookie使用机制 

2.2cookie不同属性的含义

2.2修改或者删除Cookie

2.3 Cookie对象的特点

2.4 Cookie对象的创建

2.5 Cookie中数据的获取

2.6 Cookie不支持中文的解决方案

2.7持久化Cookie和状态Cookie

2.8Cookie跨域问题

3.cookie的案例

4.httpSession的使用

4.1 HttpSession的工作原理

4.2HttpSession对象的特点

 4.3HttpSession对象的创建

 4.4HttpSession中数据的获取

4.5HttpSession的销毁

 4.6HttpSession生命周期

4.7HttpSession的使用注意事项

5.服务器端Session、客户端Session和Cookie的区别

6.httpSession的案例

6.1一个请求设置session

 6.2一个请求获取session

7.cookie  和 httpSession常见的问题

7.1getSession()/getSession(true)、getSession(false)的区别

7.2session cookie和session对象的生命周期是一样的吗

7.3session共享问题


1.认识Cookie对象与HttpSession

1.1概念

Cookie对象与HttpSession对象是维护客户端浏览器与服务端的会话状态的两个对象。由于HTTP协议是一个无状态的协议,所以服务端并不会记录当前客户端浏览器的访问状态,但是在有些时候我们是需要服务端能够记录客户端浏览器的访问状态的。

cookie是产生与服务端,保存在客户端的一种技术,它是以键值对的形式来保存少量文本,他的大小最多只有4K.通过每次http请求时携带这些存储的少量文本数据的方式来与服务端交互,以实现所谓状态记录的效果。

httpSession简称session,它是产生与服务端,并保存于服务端的一种技术,也是以键值对的形式来保存数据,不过相较于cookie保存的数据更多。,第一请求时,服务器会创建HttpSession,我们可以在HttpSession对象中保存一些关于用户的状态信息。

1.2会话管理

  • 一般多数情况下,是这样描述的:用户打开浏览器,在浏览器上进行一些操作,然后将浏览器关闭,表示一次会话结束。
  • 本质上的描述:从session对象的创建,到最终session对象超时之后销毁,这个才是真正意义的一次完整会话。

2.cookie的使用

2.1cookie使用机制 

维度1.每次都会被浏览器自动放在http请求头中存放多个cookie

维度2,.存储在cookie中的数据(1个键值对),每次都会被浏览器自动放在http请求头中,当然这个数据要是太大,会增加网络开销。如果这些数据并不是每个请求都需要发给服务端的数据,浏览器这设置自动处理无疑增加了网络开销;但如果这些数据是每个请求都需要发给服务端的数据(比如身份认证信息),浏览器这设置自动处理就大大免去了服务器的重复处理逻辑。所以对于那设置“每次请求都要携带的信息(最典型的就是身份认证信息)”就特别适合放在cookie中,其他类型的数据就不适合了。

2.2cookie不同属性的含义

 

 可见response httpHeader中返回了所有的 Cookie, Request Headers中包含了所有Cookie。Cookie是以键值对的形式存储的(name和value)。当然对于一个完整cookie来说除了name,value还有其他的属性,下面是整理出来的几个常用属性。

当maxAge属性为负数,则表示该Cookie只是一个临时Cookie,不会被持久化,仅在本浏览器窗口或者本窗口打开的子窗口中有效,关闭浏览器后该Cookie立即失效。

        Cookie cookie = new Cookie("mcrwayfun",System.currentTimeMillis()+"");
        // MaxAge为负数,是一个临时Cookie,不会持久化
        cookie.setMaxAge(-1);
        resp.addCookie(cookie);

可以看到,当MaxAge为-1时,时间已经过期

那么maxAge设置为负值和0到底有什么区别呢?

maxAge设置为0表示立即删除该Cookie,如果在debug的模式下,执行上述方法,可以看见cookie立即被删除了。

maxAge设置为负数,能看到Expires属性改变了,但Cookie仍然会存在一段时间直到关闭浏览器或者重新打开浏览器。
 

2.2修改或者删除Cookie

HttpServletResponse提供的Cookie操作只有一个addCookie(Cookie cookie),所以想要修改Cookie只能使用一个同名的Cookie来覆盖原先的Cookie。如果要删除某个Cookie,则只需要新建一个同名的Cookie,并将maxAge设置为0,并覆盖原来的Cookie即可。

新建的Cookie,除了value、maxAge之外的属性,比如name、path、domain都必须与原来的一致才能达到修改或者删除的效果。否则,浏览器将视为两个不同的Cookie不予覆盖。

值得注意的是,从客户端读取Cookie时,包括maxAge在内的其他属性都是不可读的,也不会被提交。浏览器提交Cookie时只会提交name和value属性,maxAge属性只被浏览器用来判断Cookie是否过期,而不能用服务端来判断。

我们无法在服务端通过cookie.getMaxAge()来判断该cookie是否过期,maxAge只是一个只读属性,值永远为-1。当cookie过期时,浏览器在与后台交互时会自动筛选过期cookie,过期了的cookie就不会被携带了。

2.3 Cookie对象的特点

  Cookie使用字符串存储数据

Cookie使用Key与Value结构存储数据

 单个Cookie存储数据大小限制在4097个字节

 Cookie存储的数据中不支持中文,Servlet4.0中支持

 Cookie是与域名绑定所以不支持跨一级域名访问(默认只能在站内使用)

Cookie对象保存在客户端浏览器内存上或系统磁盘中

Cookie分为持久化Cookie(保存在磁盘上)与状态Cookie(保存在内存上)

浏览器在保存同一域名所返回Cookie的数量是有限的。不同浏览器支持的数量不同,Chrome浏览器为50个

浏览器每次请求时都会把与当前访问的请求中的所有的Cookie,提交到服务端。一个cookie只存储一个键值对。一个请求中可存储多个cookie。

2.4 Cookie对象的创建

Cookie cookie = new Cookie("key","value")
服务端(后台代码)通过new关键字创建Cookie对象

response.addCookie(cookie)

服务端(后台代码)通过HttpServletResponse对象将Cookie传递给客户端浏览器。

2.5 Cookie中数据的获取

通过HttpServletRequest对象获取Cookie,返回Cookie数组。

Cookie[] cookies = request.getCookies()

可见cookie的获取前端可以获取,后台也可以获取,只需要从httpServletRequest中拿就行。

2.6 Cookie不支持中文的解决方案

在Servlet4.0版本之前的Cookie中是不支持中文存储的,如果存储的数据中含有中文,代码会直接出现异常。我们可以通过对含有中文的数据重新进行编码来解决该问题。在Servlet4.0中的Cookie是支持中文存储的。

 
 
可以使用对中文进行转码处理

URLEncoder.encode("content","code")

将内容按照指定的编码方式做URL编码处理。

URLDecoder.decode("content","code")

将内容按照指定的编码方式做URL解码处理。

2.7持久化Cookie和状态Cookie

状态Cookie:浏览器会缓存Cookie对象。浏览器关闭后Cookie对象销毁。

持久化Cookie:浏览器会对Cookie做持久化处理,基于文件形式保存在系统的指定目录中。在Windows10系统中为了安全问题不会显示Cookie中的内容。

当Cookie对象创建后默认为状态Cookie。可以使用Cookie对象下的cookie.setMaxAge(60)方法设置失效时间,单位为秒。一旦设置了失效时间,那么该Cookie为持久化Cookie,浏览器会将Cookie对象持久化到磁盘中。当失效时间到达后文件删除。

2.8Cookie跨域问题

3.cookie的案例

package org.example;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @Author:
 * @Description: MircoMessage:Mark_7001
 */
@WebServlet(urlPatterns = "/servlet3.do")
public class Servlet2 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 通过响应对象,向浏览器响应一些Cookie
        Cookie c1 = new Cookie("age", "10");// 状态Cookie 重启即清除
        Cookie c2 = new Cookie("gender", "男");// 持久化Cookie 让浏览器保留1分钟
        c2.setMaxAge(60);// 秒钟    持久化Cookie 让浏览器保留1分钟
        resp.addCookie(c1);
        resp.addCookie(c2);
    }
}

package com.mashibing.test;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.ws.WebEndpoint;
import java.io.IOException;
/**
 * @Author: Ma HaiYang
 * @Description: MircoMessage:Mark_7001
 */
@WebServlet(urlPatterns = "/servlet2.do")
public class Servlet2 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 读取请求中的Cookie
        Cookie[] cookies = req.getCookies();
        //cookies不为null
        if(null != cookies){
            for (Cookie cookie : cookies) {
                System.out.println(cookie.getName()+"="+cookie.getValue());
            }
        }
    }
}

4.httpSession的使用

4.1 HttpSession的工作原理

在这里插入图片描述

 1. 打开浏览器,在浏览器上发送首次请求
 2. 服务器会创建一个HttpSession对象,该对象代表一次会话
 3. 同时生成HttpSession对象对应的Cookie对象,如果服务器是tomcat ,则Cookie对象的name是jsessionid,Cookie的value是32位长度的字符串(jsessionid=xxxx)。Tomcat提供jsessionId值得生成方式:随机数+时间戳+jvmid.

        另外,session的使用是离不开cookie的,因为session的key 是通过Cookie的方式传给浏览器的。
 4. 服务器将Cookie的value和HttpSession对象绑定到session列表中
 5. 服务器将Cookie完整发送给浏览器客户端
 6. 浏览器客户端将Cookie保存到缓存中
 7. 只要浏览器不关闭,Cookie就不会消失
 8. 当再次发送请求的时候,会自动提交缓存中当的Cookie
 9. 服务器接收到Cookie,验证该Cookie的name是否是jsessionid,如是,则获取该Cookie的value
 10. 通过Cookie的value去session列表中检索对应的HttpSession对象 

分析一下,如果我们在HttpSession对象中保存一些关于用户的状态信息,那么有了session技术后,不就可以让http协议,或者说请求有了状态嘛。

要注意的是:
当浏览器关闭之后,缓存中的cookie消失,这样客户端下次再访问服务器的时候就无法获取到服务器端的session对象了。这就意味着会话已经结束,但是并不代表服务器端的session对象马上被回收,session对象仍然在session列表中存储,当长时间没有用户访问这个session对象了,我们称作session超时,此时web服务器才会回收session对象。
 

4.2HttpSession对象的特点

HttpSession保存在服务端

HttpSession可以存储任何类型的数据

HttpSession使用Key与Value结构存储数据 value是Object类型

HttpSession存储数据大小无限制

 4.3HttpSession对象的创建

HttpSession对象的创建是通过request.getSession()方法来创建的。客户端浏览器在请求服务端资源时,如果在请求的cookie中没有key为jesessionId的cookie,getSession()方法将会为这个客户端浏览器创建一个新的HttpSession对象,并将这个对象放入session map表中,同时会对应的生成一个key为jessionId(如果是tomcat服务器的话),value为32位长度的字符串的cookie。这个cookie和session的关系是,

cookie的key是固定的"jessionId",cookie的value是session对象在session map表中的key。

然后在响应中通过Cookie写回给客户端浏览器。
 

浏览器再次请求服务器时,如果在请求中包含了key为jesessionId的cookie,则获取该Cookie的value。通过Cookie的value去session列表中检索对应的HttpSession对象 。然后返回,然后进行业务上的逻辑处理。如果sessiono map 表中 没有SessionID,则getSession()方法将会为这个客户端浏览器创建一个新的HttpSession对象

getSession()方法还有一个重载方法getSession(true|false)。当参数为true时与getSession()方法作用相同。当参数为false时则只去根据SessionID查找是否有与这个客户端浏览器对应的HttpSession,如果有则返回,如果没有SessionID则不会创建新的HttpSession对象。

 

 4.4HttpSession中数据的获取

将数据存储到HttpSession对象中

session.setAttribute("key",value)

根据key获取HttpSession中的数据,返回Object

Object value = session.getAttribute("key")

获取HttpSession中所有的key,返回枚举类型

Enumeration<String> attributeNames = session.getAttributeNames()

根据key删除HttpSession中的数据

session.removeAttribute("key")

根据获取当前HttpSession的SessionID,返回字符串类型

String id = session.getId()

4.5HttpSession的销毁

HttpSession的销毁方式有两种:

Ø  通过web.xml文件指定超时时间(最大不活动时间)

Ø  通过HttpSession对象中的invalidate()方法销毁当前HttpSession对象

   我们可以在web.xml文件中指定HttpSession的超时时间,当到达指定的超时时间后(默认是30分钟),容器就会销该HttpSession对象,单位为分钟。该时间对整个web项目中的所有HttpSession对象有效。时间的计算方式是根据最后一次请求时间作为起始时间。如果有哪个客户端浏览器对应的HttpSession的失效时间已到,那么与该客户端浏览器对应的HttpSession对象就会被销毁。其他客户端浏览器对应的HttpSession对象会继续保存不会被销毁。

<session-config>

    <session-timeout>1</session-timeout>

  </session-config>

我们也可以在Tomcat的web.xml文件中配置HttpSession的销毁时间。如果在Tomcat的web.xml文件中配置了HttpSession的超时时间对应的是Tomcat中所有的Web项目都有效。

 

相当于配置了全局的HttpSession超时时间。如果我们在Web项目中配置了超时时间,那么会以Web项目中的超时时间为准。

                       

invalidate()方法是HttpSession对象中所提供的用于销毁当前HttpSession的方法。我们通过调用该方法可以销毁当前HttpSession对象。

 4.6HttpSession生命周期

在HttpSession对象生命周期中没有固定的创建时间与销毁时间。何时创建取决于我们什么时候第一次调用了getSession()或getSession(true)的方法。HttpSession对象的销毁时间取决于超时时间的到达以及调用了invalidate()方法。如果没有超时或者没有调用invalidate()方法,那么HttpSession会一直存储。默认超时时间为30分钟(Tomcat的web.xml文件配置的时间就是默认超时时间)。

4.7HttpSession的使用注意事项

HttpSession对象是保存在服务端的,所以安全性较高。我们可以在HttpSession对象中存储数据,但是由于HttpSession对象的生命周期不固定,所以不建议存放业务数据。一般情况下我们只是存放用户登录信息。

5.服务器端Session、客户端Session和Cookie的区别

Ø  cookie数据存放在客户的浏览器或系统的文件中,而HttpSession中的数据存放在服务器中。

Ø  cookie不安全,而HttpSession是安全的。

Ø  单个cookie保存的数据不能超过4K,很多浏览器都限制一个域名保存cookie的数量。而HttpSession没有容量以及数量的限制。

6.httpSession的案例

6.1一个请求设置session

package org.example;


import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;


/**
 * @Author:
 * @Description: MircoMessage:Mark_7001
 */
@WebServlet(urlPatterns = "/servlet1.do")
public class Servlet1 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) {

        HttpSession httpSession = req.getSession();
        httpSession.setAttribute("name", "msb");
        httpSession.setAttribute("password", "12345");
        // httpSession.invalidate();

    }
}

 6.2一个请求获取session

package org.example;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;

/**
 * @Author:
 * @Description: MircoMessage:Mark_7001
 */
@WebServlet(urlPatterns = "/servlet2.do")
public class Servlet2 extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        String name = (String) session.getAttribute("name");
        System.out.println("name = " + name);
        String password = (String) session.getAttribute("password");
        System.out.println("password = " + password);

    }
}

结果:

 

 

7.cookie  和 httpSession常见的问题

7.1getSession()/getSession(true)、getSession(false)的区别

getSession()/getSession(true):当session存在时返回该session,否则新建一个session并返回该对象

getSession(false):当session存在时返回该session,否则不会新建session,返回null

7.2session cookie和session对象的生命周期是一样的吗

当用户关闭了浏览器虽然session cookie已经消失,但session对象仍然保存在服务器端

7.3session共享问题

当下的互联网网站为了提高网站安全性和并发量,服务端的部署的服务器的数量往往是大于或等于两台,多台服务器对外提供的服务是等价的,但是不同的服务器上面肯定会有不同的web容器,由上面的讲述我们知道session的实现机制都是web容器里内部机制,这就导致一个web容器里所生成的session的id值是不同的,因此当一个请求到了A服务器,浏览器得到响应后,客户端存下的是A服务器上所生成的session的id,当在另一个请求分发到了B服务器,B服务器上的web容器是不能识别这个session的id值,更不会有这个sessionID所对应记录下来的信息,这个时候就需要两个不同web容器之间进行session的同步。
一般大型互联公司的网站都是有一个个独立的频道所组成的,例如我们常用的百度,会有百度搜索,百度音乐,百度百科等等,我相信他们不会把这些不同频道都给一个开发团队完成,应该每个频道都是一个独立开发团队,因为每个频道的应用的都是独立的web应用,那么就存在一个跨站点的session同步的问题,跨站点的登录可以使用单点登录的(SSO)的解决方案,但是不管什么解决方案,跨站点的session共享任然是逃避不了的问题。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值