(3) 数据数量
一个Cookie对象只能存储一个共享数据,所以这也是为什么当我们去创建Cookie类型的变量的时候,变量名必须不一样。
HttpSession是使用map集合存储共享数据,所以可以存储任意数量共享数据,所以只需要使用会话域对象调用setAttribute方法即可。
(4)参照物
Cookie相当于客户在服务端【会员卡】
HttpSession相当于客户在服务端【私人保险柜】,放的比cookie多
三.代码实现
======
此处我们还是拿OneServelet和TwoServlet来举例:
同一个网站(myWeb)下OneServlet将数据传递给TwoServlet
首先在OneServlet中将数据存入到我们的session中
public class OneServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) {
//1.调用请求对象向Tomcat索要当前用户在服务端的私人储物柜
HttpSession session = request.getSession();
//2.将数据添加到用户私人储物柜
session.setAttribute(“key1”, 10);
}
}
浏览器访问/myWeb中T的woServlet,在TwoServlet中编写代码来获取我们的数据。
public class TwoServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) {
//1.调用请求对象向Tomcat索要当前用户在服务端的私人储物柜
HttpSession session = request.getSession();
//2.从会话作用域对象得到OneServlet提供的共享数据
Integer num = session.getAttribute(“key1”);
System.out.println(“获取到的共享数据值为=”+num);
}
}
当然假如我们的用户在获取共享数据的时候不想去使用包装类强转,想使用我们的基本数据类型强转也可以,此时就需要用到一个方法叫做getAttributeNames方法,这个方法可以获取到我们session中使用map集合存储共享数据时的key值,下面来看具体的代码实现吧:此处只需要重写我们TwoServlet中的代码即可。
public class TwoServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.调用请求对象向Tomcat索要当前用户在服务端的私人储物柜
HttpSession session = req.getSession();
//2.从会话作用域对象得到OneServlet提供的共享数据
Enumeration keynames=session.getAttributeNames();
while(keynames.hasMoreElements()){
//获取到map集合中的每一个key值
String eachkeyname=(String)keynames.nextElement();
int eachvalue=(int)session.getAttribute(“key1”);
System.out.println(“key值为”+eachkeyname+“value值为”+eachvalue);
}
}
}
注意事项:
1:当我们使用getAttributeNames获取我们存入到map集合中的所有数据的时候,这个方法的返回值是一个枚举对象,所以需要将我们所获取的所有key值赋给我们的枚举对象。
2:当获取到所有的key值时,下一步需要使用while循环来遍历我们的枚举对象,方法为hasMoreElements()。
3:循环内部首先需要获取每一个具体的key值,那么就需要使用我们的nextElements()方法来获取,注意nextElements()方法的返回值为Object,所以此处涉及到我们的强转,假设之前我们的key值类型为String,那么此处的强转类型便为String.
4:当获取到我们的key值后,此时就需要获取我们的value值,获取方式还是使用我们的Httpsession对象的属性getAttribute方法,getAttribute方法的返回值仍为Object,所以此时获取我们的value值时仍然涉及到我们的强转,因为在OneServlet中我们存储的时候的value值为整形,所以此处的强转类型为int即可。
🆗,说到这里,一个问题戛然而生,之前我们在使用getAttribute方法获取整形类型的共享数据的时候,我们的强转类型为Integer,为什么当我们使用getAttributeNames方法后,此处当我们获取到我们的整型类型的共享数据的时候,我们的强转类型就变为了int呢?
首先先来看之前我们没有使用getAttributeNames的时候,此时假如用户给我们的key1赋了一个null值,然后在另一端接收的时候用户并不知道这个数据是否为null,假如此时不使用包装类进行强转,使用基本类型去进行强转,就会发生空指针异常,因为基本数据的默认值例如int为0,而其包装类Integer的话默认值为null,所以此时使用int进行强转的话,就相当于将null赋值给基本数据类型int,那么就会发生空指针异常,但是包装类就不会发生,因为其是可以存储null的。
一般在实际开发中我们都会拿包装类来进行传参,因为是可以进行
当我们使用getAttributeNames后,此时就相当于一个一个的从Map集合中将key值取出来,此时的key值都是有明确的value值与之对应的,所以不会发生空指针异常,那么即使在获取整形的value值时使用了基本数据类型进行强转也不会发生任何异常。
4.Http服务器如何将用户与HttpSession关联起来?
===============================
答案当然是使用cookie来进行连接,下面我们来看一张图来进行理解:
当用户第一次访问OneServlet的时候,会在OneServlet中使用请求对象代替Tomcat索要当前的HttpSession对象,在服务器端内部,我们的Tomcat会自动为每一个HttpSession对象设置一个编号(箱号),名为JSESSIONID,当我们在OneServlet中使用setAttribute方法存储数据到我们的HttpSession对象后,此时我们的HttpSession对象便会直接放在我们的Http服务器端,然后将我们的编号JSESSIONID放入到我们的cookie当中,再将我们的cookie放入到http响应协议包的响应头中返回给我们的浏览器,存在我们浏览器的缓存中,如上图所示。
当同一用户在同一网站下第二次访问TwoServlet时,此时发给TwoServlet的请求协议包中便会放入我们之前所收到的来自服务器端的cookie,这个cookie被放入了请求协议包中的请求头中,然后此时服务器端接收到我们的浏览器请求后,tomcat会根据cookie当中的JSESSIONID来判断当前用户是否之前索要到了HttpSession对象以及哪个HttpSession对象是当前这个用户的,从而就找到了之前这个用户第一次请求时在session中用于存储的数据HttpSession对象,然后就可以使用getAttribute方法来获取到数据了。
五.getSession() 与 getSession(false)的区别
=======================================
1.getSession()
如果当前用户在服务端已经拥有了自己的私人储物柜.要求tomcat将这个私人储物柜进行返回.
如果当前用户在服务端尚未拥有自己的私人储物柜,要求tocmat为当前用户创建一个全新的私人储物柜.
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!**
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!