【圣诞篇】Servlet之Cookie与Session的爱恨情仇

本文介绍了Cookie的作用、存储位置、在不同web开发中的普遍性,以及在Java中如何创建和管理Cookie。同时,讨论了Cookie的路径绑定、有效期设置及其与服务器交互的方式。此外,还提及了浏览器禁用Cookie的情况。对于Session,文章通过测试场景解释了其在不同请求和项目中的行为。
摘要由CSDN通过智能技术生成

Cookie 

1、Cookie是什么? Cookie作用? Cookie保存在哪里?

  • 翻译过来:曲奇饼干
  • Cookie可以保存会话状态,但是这个会话状态是保留在客户端上,只要Cookie清除,或者Cookie失效,这个会话状态就没有了
  • Cookie可以保存在浏览器的缓存中,浏览器关闭则Cookie消失
  • Cookie也可以保存在客户端的硬盘文件中,浏览器关闭Cookie还在,除非Cookie失效

 2、Cookie只有在javaweb中有吗?

  • Cookie不止是在javaweb中存在
  • 只要是web开发,只要是B/S架构的系统,只要是基于HTTP协议,就有Cookie的存在
  • Cookie这种机制是HTTP协议规定的

         
3、Cookie实现的功能,常见的有哪些?

  •          保留购物车商品的状态在客户端上

         *      十天内免登录
         *      .......
         *
4、在java中Cookie被当做类来处理,使用new运算符可以创建Cookie对象,而且Cookie由两部分组成
         *    分别是Cookie的name和value,name和value都是字符串类型String
         *
5、在java程序中怎么创建Cookie?
         *      Cookie cookie = new Cookie(String cookieName,String cookieValue);
         *
6、服务器可以一次向浏览器发送多个Cookie
         *
7、默认情况下,服务器发送Cookie给浏览器之后,浏览器将Cookie保存在缓存当中,只要不关闭浏览器,Cookie永远存在,并且有效
         *  当浏览器关闭之后,缓存中的Cookie被清除
         *
8、在浏览器客户端无论是硬盘文件中还是缓存中保存的Cookie,什么时候会再次发送给服务器呢?
         *    浏览器会不会提交发送这些Cookie给服务器,是和请求路径有关系的
         *    请求路径和Cookie是紧密关联的
         *    不同的请求路径会发送提交不同的Cookie
         *
9、默认情况下Cookie会和哪些路径绑定在一起?
         *      /prj-servlet-18 项目名
         *      /prj-servlet-18/test/createAndSendCookieToBrowser 请求服务器,服务器生成Cookie,并将Cookie发送到浏览器客户端
         *      这个浏览器中的Cookie会默认和“test/”这个路径绑定在一起
         *     也就是说,以后只要发送“test/”请求,Cookie一定会提交给服务器
         *     /prj-servlet-18/a 请求服务器,服务器生成Cookie,并将Cookie发送给浏览器客户端
         *     这个浏览器中的Cookie会默认和“prj-servlet-18/”这个路径绑定在一起
         *     也就是说,以后只要发送“prj-servlet-18/”请求,Cookie一定会提交给服务器
         *
10、其实路径是可以指定的,可以通过java程序进行设置,保证Cookie和某个特定的路径绑定在一起。
         *      假设,执行了这样的程序:cookie.setPath("/prj-servlet-18/king");
         *      那么:Cookie将和"/prj-servlet-18/king"路径绑定在一起
         *      只有发送“/prj-servlet-18/king”请求路径,浏览器才会提交Cookie给服务器
         *
11、默认情况下,没有设置Cookie的有效时长,该Cookie被默认保存在浏览器的缓存当中
         *      只要浏览器不关闭Cookie存在,只要关闭浏览器Cookie消失,我们可以通过设置Cookie的有效时长,以保证Cookie保存在硬盘文件当中
         *      但是这个有效时长必须是>0的,换句话说,只要设置Cookie的有效时长大于0,则该Cookie会被保存在客户端硬盘文件当中
         *      有效时长过去之后,则硬盘文件当中的Cookie失效
         *      cookie有效时长 = 0 直接被删除
         *      cookie有效时长 < 0 不会被存储
         *      cookie有效时长 > 0 存储在硬盘文件当中
         *      cookie.setMaxAge(60 * 60);  设置1小时有效
         *
12、浏览器提交Cookie给服务器,服务器怎么接收Cookie?
         *      Cookie[] cookies = request.getCookies();
         *      if(cookies != null){
         *          for(Cookie cookie : cookies){
         *              String cookieName = cookie.getName();
         *              String cookieValue = cookie.getValue();
         *              System.out.println(cookieName + "=" + cookieValue);
         *          }
         *      }
13、浏览器可以禁用Cookie,是什么意思?

  •          表示服务器发送过来的Cookie,我浏览器不要,不接收
  •          服务器还是会发送Cookie的,只不过浏览器不再接收

14、示例

  • 创建Cookie对象

         *         Cookie cookie1 = new Cookie("username","zhangsan");
         *         Cookie cookie2 = new Cookie("password","123");
         *

  • 设置Cookie的关联路径

         *         //cookie1.setPath(request.getContextPath() + "/king");
         *         //cookie2.setPath(request.getContextPath() + "/king");
         *

  • 设置Cookie的有效期

         *         cookie1.setMaxAge(60 * 60);
         *         cookie2.setMaxAge(60 * 60 * 24);
         *

  • 将Cookie对象发送给浏览器客户端

         *         response.addCookie(cookie1);
         *         response.addCookie(cookie2);


public class Cookie {
    public static void main(String[] args) {
        /**
         */一、Cookie
         *
         * 
         *
         * 
         *
         *      //从request中获取所有的Cookie
         * 		Cookie[] cookies = request.getCookies();
         * 		String username = null;
         * 		String password = null;
         * 		if(cookies != null){
         * 			遍历Cookie
         * 			for(Cookie cookie : cookies){
         * 				String cookieName = cookie.getName();
         * 				String cookieValue = cookie.getValue();
         * 				if("username".equals(cookieName)){
         * 					username = cookieValue;
         *                 }else if("password".equals(cookieName)){
         * 					password = cookieValue;
         *                }			
         *           }
         * 		}
         */
        
    }
}

Session 

测试(1):在同一个web项目中编写两个Servlet类firstServlet和secondServlet,通过前端发起请求,获取当前的session对象

package com.exercise.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class firstServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      String ip=request.getRemoteAddr();
        HttpSession session=request.getSession();
        System.out.println(ip+"'s session="+session);
    }
}

第一次请求:

 当关闭浏览器,重新打开浏览器访问时:

测试(2):同一个浏览器窗口访问不同的web项目(比如第一次访问京东,第二次访问淘宝),获取当前的session

第一个web项目: 

 第二个web项目:

package com.exercise.login;

public class Test {
    public static void main(String[] args) {
        /**
         */二、Session
         *
         * 1、Session表示会话,不止是在javaweb中存在,只要是web开发,都有会话这种机制
         *
         * 2、在java中会话对应的类型是:javax.servlet.http.HttpSession,简称session/会话
         *
         * 3、Cookie可以将会话状态保存在客户端,HttpSession可以将会话状态保存在服务器端
         *
         * 4、HttpSession对象是一个会话级别的对象,一次会话对应一个HttpSession对象
         *
         * 5、什么是一次会话?
         *      “目前”可以这样理解:用户打开浏览器,在浏览器上发送多次请求,直到最终关闭浏览器,表示一次完整的会话
         *
         * 6、在会话进行过程中,web服务器一直为当前这个用户维护着一个会话对象/HttpSession
         *
         * 7、在WEB容器中,WEB容器维护了大量的HttpSession对象,换句话说,在WEB容器中应该有一个“session列表”
         *      思考:为什么当前会话中的每一次请求可以获取到属于自己的会话对象? session的实现原理?
         *      (1)打开浏览器,在浏览器上发送首次请求
         *      服务器会创建一个HttpSession对象,该对象代表一次会话
         *      同时生成HttpSession对象对应的Cookie对象,并且Cookie对象的name是JSESSIONID(比较特殊)
         *      Cookie的value是32位长度的字符串,value为session对象的id
         *      服务器将Cookie的value和HttpSession对象绑定到session列表中
         *      服务器将Cookie完整发送给浏览器客户端
         *      浏览器客户端将Cookie保存到缓存中,只要浏览器不关闭,Cookie不会消失
         *      (2)当再次发送请求的时候,会自动提交缓存当中的Cookie
         *      服务器接收到Cookie,验证该Cookie的name确实是:JSESSIONID,然后获取该Cookie的value
         *      通过Cookie的value(session对象的id)去session列表中检索对应的HttpSession对象,从而区分不同用户
         * 8、和HttpSession对象关联的这个Cookie的name是比较特殊的,在java中就叫做:jsessionid
         *
         * 9、浏览器禁用Cookie会出现什么问题?怎么解决?
         *      浏览器禁用Cookie,则浏览器缓存中不再保存Cookie
         *      导致在同一个会话中,无法获取到对应的会话对象
         *      禁用Cookie之后,每一次获取的会话对象都是新的
         *      浏览器禁用Cookie之后,若还想拿到对应的Session对象,必须使用URL重写机制,怎么重写URL:
         *      http://localhost/prj-servlet-21/user/accessMySelfSession;
         *      jsessionid=D3E9985BC5FD4BD05018BF2966863E94(记下value,浏览器地址栏上 ;value)
         *      重写URL会给编程带来难度/复杂度,所以一般的web站点是不建议禁用Cookie的,建议浏览器开启Cookie
         *
         * 10、浏览器关闭之后,服务器端对应的session对象会被销毁吗?为什么?
         *      浏览器关闭之后,服务器不会销毁session对象
         *      因为B/S架构的系统基于HTTP协议,而HTTP协议是一种无连接/无状态的协议
         *      什么是无连接/无状态?
         *      请求的瞬间浏览器和服务器之间的通道是打开的,请求响应结束之后,通道关闭
         *      这样做的目的是降低服务器的压力
         *
         * 11、session对象在什么时候被销毁?
         *      web系统中引入了session超时的概念
         *      当很长一段时间(这个时间可以配置)没有用户再访问该session对象,此时session对象超时,web服务器自动回收session对象
         *      可配置在:web.xml文件中,默认是30分钟,一般设置2小时
         *      <session-config>
         *          <session-timeout>120</session-timeout>
         *      </session-config>
         *
         * 12、什么是一次会话呢?
         *      一般多数情况下,是这样描述的:用户打开浏览器,在浏览器上进行一些操作,然后将浏览器关闭,表示一次会话结束
         *      本质上的描述:从session对象的创建,到最终session对象超时之后销毁,这个才是真正意义的一次完整会话
         * 13、关于javax.servlet.http.HttpSession接口中常用方法:
         *      void setAttribute(String name, Object value)
         *      Object getAttribute(String name)
         *      void removeAttribute(String name)
         *      void invalidate() 销毁session
         *
         * 14、ServletContext、HttpSession、HttpServletRequest接口的对比:
         *      14.1 以上都是范围对象:
         *          ServletContext application; 是应用范围
         *          HttpSession session; 是会话范围
         *          HttpServletRequest request; 是请求范围
         *      14.2 三个范围的排序:
         *          application > session > request
         *      14.3 三者区别:
         *          application完成跨会话共享数据
         *          session完成跨请求共享数据,但是这些请求必须在同一个会话当中
         *          request完成跨Servlet共享数据,但是这些Servlet必须在同一个请求当中【转发】
         *      14.4 使用原则:由小到大尝试(越小耗费资源越少),优先使用小范围
         *          例如:登录成功之后,已经登录的状态需要保存起来,可以将登录成功的这个状态保存到session对象中
         *          登录成功状态不能保存到request范围中,因为一次请求对应一个新的request对象
         *          登录成功状态也不能保存到application范围中,因为登录成功状态是属于会话级别的,不能所有用户共享
         *
         * 15、补充HttpServletRequest中的方法:
         *      HttpSession session = request.getSession(); 
         *      获取当前的session,获取不到,则新建session
         *      HttpSession session = request.getSession(true); 
         *      获取当前的session,获取不到,则新建session
         *      HttpSession session = request.getSession(false); 
         *      获取当前的session,获取不到,则返回null(退出系统)
         *      HttpSession session = request.getSession(false);
         *      if(session != null){
         *      销毁session
         *      session.invalidate();
         *      }
         */

    }
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小馒头爱学Java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值