cookie和session笔记

 cookie简介:
    cookie来源:HTTP协议是一种无状态协议,即本次请求与下次请求无关系。而在不同请求时需要进行数据传递,需要一种可以进行请求间数据传递的会话跟踪技术,cookie因此而生。
    cookie机制:用户提交第一次请求后,由服务器生成(是一种保存在客户端的信息载体技术,cookie可被清空,可失效),并将其封装至响应头,以响应形式发给客户端,
    客户端收到响应后将cookie保存在客户端。当客户端再次发送同类请求后,在请求中会携带保存在客户端的cookie数据发送给服务端。由服务器对会话进行跟踪。
    cookie属性:属于web技术,非javaweb专项技术;由若干键值对构成cookie("name","value");

  注意:同类请求:http://localhost:8080/project/xxx/ccc/some  同类请求即资源路径相同的请求    http://localhost:8080/project/xxx/ccc  资源路径,(它在web.xml的<url-pattern>中),中间的project为项目名;some  资源名称,即你写的文件名。
    只要你写的 http://localhost:8080/project/xxx/ccc 路径相同,则是同类路径。
        
javaWeb中的cookie:
    1,javaWeb中的cookie属于一个类。
    2,创建cookie:Cookie(String  name,String  value);例:Cookie cookie  =  new  Cookie("student","zyz");
    3,响应中添加cookie:response.addCookie("");响应中的方法。例:response.addCookie(cookie  );
    4,指定cookie绑定路径:Cookie.setPath(request.getContextPath()+"xxx/ooo/aaa");
    5,设置cookie有效期,此值为整数,单位秒:
        cookie.setMaxAge(60*60);有效期一小时。    //该设置值      >  0,表示cookie存放在客户端硬盘。
                              该设置值      <  0,与不设置一样,将cookie存放在浏览器缓存。会话结束时cookie消失,即浏览器关了就没了。
                              该设置值      =  0,表示cookie一生成就马上失效。
    6,获取请求中的cookie:
        Cookie[ ] cookies  =  request.getCookies();
    7,遍历cookie:
        for(Cookie  cookie  :  cookies)  {
            System.out.println(cookie.getName()  +  "==="  +  cookie.getValue());
            if(cookies.getNmae().equals("student")  &&  cookie.getValue().equals("zyz"))  {
                    //你需要的操作
                }else  if  {
                    //你需要的操作
                }
        }
    cookie用法:创建cookie (some文件),响应cookie    ;获取cookie(other文件),再进行你需要的操作。 两者在同路径下。
    cookie禁用:在浏览器中可以设置禁用cookie,去选“接受来自站点的cookie”禁用的是自己客户端的cookie 。cookie被禁用后cookie仍然可以生成,但request无法获取cookie,很多网站也将无法访问。

    javaWeb中的session  (javaWeb开发中,Session是以javax.servlet.http.HttpSession的接口对象形式出现)

    session的三个域书性空间对比:
        1,ServletContext,置入其中的域属性是整个应用范围的,可以完成跨会话共享数据。应用启动时创建,域属性空间创建,不删除则一直存在整个应用。空间很长。
        2,HttpSession,置入其中的域属性是会话范围的,可以完成跨请求共享数据。
        3,HrrpServletRequest,置入其中的域属性是请求范围的,可以跨servlet共享数据,但这写servlet必须在同一请求中。生命周期很短,域属性空间也很短。
        三者使用原则:保证需求前提下,优先使用最小,节省服务器内存,保证数据安全性。ServletContext  >  HttpSession  >  HrrpServletRequest,

  session简介

  来源:也是web开发的会话跟踪技术,同样是服务器生成。不同在cookie是将会话状态保存在客户端,session则是将会话状态保存在服务端。
    什么是会话:用户打开浏览器,发出第一次请求,到浏览器关闭,表示一次会话完成。

    HttpSession的三个方法:
          public void setAttribute(String name,Object value) {}        用于向session的域属性空间中放入指定名称,指定值的域属性。
          public void getAttribute(String name) {}            用于从session的域属性空间中读取指定名称的域属性。
          public void removeAttribute(String name) {}        用于向session的域属性空间中删除指定名称的域属性。
    
    在session与空间中存放数据:
        首先要获取了session对象才能存放数据。        HttpSession session=request.getSession();
        在此注意获取session对象要使用的方法,方法有两个,特性如下:
            1,getSession();无参  
            2,getSession(true/false);        
                true:如果有已创建的session就用已创建的,若没有就新建
                flase:如果有已创建的session就用已创建的,若没有就不新建,返回null
        一般情况下:1,向session域空间中写入数据用getSession(true),即getSession();方法。因为要创建session对象存储数据。
            2,而从session域空间中读数据则用getSession(false);方法。    读取数据是要读取先前创建的session对象中的数据,若选用true就会新建session对象,那session中就没有数据了。
        现在要在session域中写入属性。但是现没有session,所以要创建就getSession(true);true可以不写。

    session的工作机制
        1,写入session列表:请求到达时将jsessionID和session对象写到session列表中。
            (服务器对当前应用中的session以Map形式管理,Map称为session列表。Map的key是一个32位随机串即jsessionID,value则为session对象的引用,
             用户首次提交请求时,服务端servlet中执行到request.getSession()方法后自动生成Map.Entry对象,key据算法生成jsessionID,value则时新创建的Httosession对象;)

        2,服务器生成并发送Cookie:在将session信息写入session列表后,系统还会自动将jsessionID作为name,32位随机串作为value,以Cookie的形式存放到响应头中,并随即响应,将cookie发送至客户端;

        3,客户端接收并发送客户端:客户端接收到cookie后将其存入浏览器缓存,即客户端浏览器不关闭,浏览器中cookie不消失。当用户第二次请求时,会将缓存中的cookie伴随请求头部信息一块发送都服务端。

        4,送session列表中查找:服务端从请求中读取到客户发送的cookie,根据cookie的jsessionID的值,从Map中查找相应key所对应的value,即session对象,再对session对象的域属性进行读写操作。
        
           总结:servlet中获取session,在session中写入属性,底层服务器检测到getSession后生成随机字符串,再创建session对象,然后以32位随机字符串为key,以session对象为value放入session列表中即Map中,
                  用户首次请求servlet,服务器再放入session列表后将32为随机串包装成cookie发送给客户端浏览器(cookie的name==jsessionID,value==32位随机串),客户端浏览器接收cookie将其保存再缓存中。
                  当再次客户端请求读取数据时,会将浏览器缓存中cookie里的jsessionID放到请求头部信息中发送给服务器,服务器拿到jsessionID后就去session列表中查找,
                  找到后key后就找到了key所对应的value(存放有域属性的session),然后从中读数据。

    session失效
        在web.xml中可以通过<session-config/>标签设置session的超时时间,单位分钟。默认session超时时间为30分钟,这个时间指的是最后一次访问开始计时,在指定时常内一直未被访问的时常;    
        <session-config/>
            <session-timeout>120</session-timeout>
        <session-config/>
        若未到超时时限,HttpSession中方法,invalide()可实现失效;

    cookie禁用
           首先生成随机串,写入session列表,随机串包装成cookie==jsessionID,放入响应头,发送客户端,这是服务端的cookie。客户端接收cookie放入缓存,客户端第二次请求时会将缓存中的cookie发送给服务器,
        好的,问题来了,如果客户端禁用了cookie,那服务端发来的带有cookie的响应,客户端不会接收,不接收客户端又提交一次请求,提交给服务端的这个请求没有jsessionID大的cookie,服务端会将其看成第一次请求,
        就会再次生成随机串,包装成cookie,生成session,发送给客户端,客户端因为session禁用,又不会接收,再一次请求服务端又看成第一次请求,就成循环,问题就大了。
    
    问题:那么cookie禁用了就不能是实现会话跟踪了吗?session就不能用了吗?
        能用。  禁用cookie,客户端不接收服务端发送过来的cookie。但是会生成jsessionID,根据此次生成的jsessionID,再一次提交请求,session 还是会变,但是不会再重新生成新的cookie(也就时服务器生成32位随机数)。
        //例:      
                 http://localhost:8080/sessionandcookie/SomeSession:jsessionid=881CDDC1766E28391FS3E3E3B16669(这是上次会话生成的jsessionID,记录下来,根据这个地址进去)
            根据这个带有jsessionID的地址进去提交请求,第一次sessionID是很变,但是不会生成cookie,也不会携带有jsessionID。
            再一次刷新,会发现session也不会变,而后刷新多少次都不会变。因为根据jsessionID已经实现了会话跟踪。
        
    假设:     如果上一个人进入网页或者某宝购物后,关闭浏览器走了,我们获取了他网页的jsessionID,那我们就能进入本次会话,简单说就是进入他某宝账户,修改某些东西也是可以的。
    但是这也就牵扯但一个问题。会话什么时候结束?关闭了浏览器那算不算会话结束?
        什么是会话:
            就客户端而言:用户打开浏览器,发出第一次请求,到浏览器关闭,表示一次会话完成。
        服务端:
            第一次请求开始,session失效时候会话结束。
        关闭浏览器后服务器的session依旧没有失效,此次会话依旧可以进入。所以在使用非私人手机或电脑时要退出账户,数据解绑,session失效。

    cookie禁用后重定向时的session跟踪
        上面谈到,cookie禁用后的session跟踪需要jsessionID进行跟踪,但是这也意味着jsessionID暴露在地址栏,这会跟危险。
        那怎么才能不暴露jsessionID,而又能在cookie被禁用的情况下进行会话跟踪呢?在此引入重定向。
        例1:
        RedirectServlet_1文件    
    
            HttoSession session = request.getSession();    //获取session对象
            session.setAttribute("user" , "student");        //写入数据
            System.out.println("RedirectServlet_1 session =" +session);
            respone.sendRedirect(request.getContextPath() + "/RedirectServlet_2");

        RedirectServlet_2

            HttoSession session = request.getSession(false);    //获取session对象
            System.out.print("RedirectServlet_2 : session = " + session);
            //从session中获取指定属性
            String user = null;
            if(session != null) {
                user = (String ) session.getAttribute("user");
            }
             PrintWriter out = respone.getWriter();
            out.println("RedirectServlet_2 : user = " + user);

        这个例子是cookie被禁用后使用重定向失败的例子,结果为:
        RedirectServlet_2 : user = null
        响应头信息为:
        http://localhost:/cookieandsession/RedirectServlet_1        //响应有cookie(cookie==jsessionID),响应有信息session;
        http://localhost:/cookieandsession/RedirectServlet_2        //响应没有cookie(cookie==jsessionID),响应为null;
        重定向时候又重新提交了一次请求;
        这个案例失败了,没有跟踪到会话;
        
        例2:

        RedirectServlet_1文件    
    
            HttoSession session = request.getSession();    //获取session对象
            session.setAttribute("user" , "student");        //写入数据
            System.out.println("RedirectServlet_1 session =" +session);
            
            //加上这个方法
            String url = request.getContextPath() + "/RedirectServlet_2";
            url = response.encodeRedirectURL(url);            //解决cookie禁用后session的跟踪问题;
            response.sendRedirect(url);

        这个例子是cookie被禁用后使用重定向成功的例子,结果为:
        RedirectServlet_2 : user = null
        响应头信息为:
        http://localhost:/cookieandsession/RedirectServlet_1        //响应有cookie(cookie==jsessionID),响应有信息session;
        http://localhost:/cookieandsession/RedirectServlet_2        //响应有cookie(cookie==jsessionID),响应为student;
        此次重定向的请求cookie的jsessionID一样。
    
        如果cookie没有被禁用,结果也是如此。只要加了这个方法不管cookie是否被禁用session都可以被禁用。但是最好不要禁用cookie,禁用后看似安全其实不安全。
        cookie被禁用后进行session跟踪,jsessionID也就暴露了,并不安全。
        

    cookie禁用后非重定向的session跟踪
    
        超链接URL的重写:
            HttpServletResponse具有一个方法 encodeURL(),可以完成对类似超链接的非重定向页面跳转的URL重写,即在其具体路径后会自动添加jsessionID。
            cookie没有被禁用时
                例1:
                    RedirectServlet_1文件    
    
                        HttoSession session = request.getSession();    //获取session对象
                        session.setAttribute("user" , "student");        //写入数据
                        respone.setContentType("/text/html;charset = utf -8");
                        PrintWriter out = respone.getWriter();
                        out.println("<a href = 'RedirectServlet_2'>跳转</a>到RedirectServlet_2");
    
                    省略RedirectServlet_2,与上一致
    
                        输出结果:RedirectServlet_2 :user: = student


            cookie被禁用时
                没有使用encode URL();方法
                    输出结果:RedirectServlet_2 :user: =null

                使用encode URL();方法        
    
                例1:
                    RedirectServlet_1文件    
    
                        HttoSession session = request.getSession();    //获取session对象
                        session.setAttribute("user" , "student");        //写入数据
                        respone.setContentType("/text/html;charset = utf -8");

                        PrintWriter out = respone.getWriter();
                        String url = "RedirectServlet_2";
                        //解决cookie禁用后,非重定向时的session跟踪问题;
                        url = response.encodeURL(url);
                        out.println("<a href = 'RedirectServlet_2'>跳转</a>到RedirectServlet_2");
    
                    省略RedirectServlet_2,与上一致
    
                        输出结果:RedirectServlet_2 :user: = student

以上为学习b站大佬后的笔记,大佬写的很详尽,再次附上学习地址  https://www.bilibili.com/video/BV1s4411z7zq

原文地址:https://www.cnblogs.com/-zyz/p/12595056.html