一、会话控制
1.为什么会出现会话控制
HTTP协议的特点:
纯文本
无状态
浏览器不能区分多个请求是否来自同一个用户
但是有时候我们需要让浏览器知道多个请求来自同一个用户,比如:网上购物。所以就出现了会话控制
会话控制涉及到两种技术
Cookie
Session
2.Cookie
Cookie就是服务器发送给浏览器的用于区分不同用户的一段信息
Cookie的运行机制
1)服务器创建一个Cookie对象
2)服务器将Cookie对象发送给浏览器
3)以后浏览器发请求就会携带着该Cookie对象
4)服务器根据Cookie对象来区分不同的用户
创建Cookie对象
[java] view plain copy
- //1.创建Cookie,Cookie对象的名称(key)不能使用中文
- Cookie cookie = new Cookie("username", "sunwukong");
- Cookie cookie2 = new Cookie("username2", "zhubajie");
- //2.将Cookie对象发送给浏览器
- response.addCookie(cookie);
- response.addCookie(cookie2);
获取Cookie对象
[java] view plain copy
- //1.获取Cookie对象
- Cookie[] cookies = request.getCookies();
- //2.遍历得到每一个Cookie对象
- if(cookies != null){
- for (Cookie cookie : cookies) {
- //获取Cookie对象的名称
- String name = cookie.getName();
- System.out.println(name);
- //获取Cookie对象的值
- String value = cookie.getValue();
- System.out.println(value);
- }
- }
修改Cookie对象
[java] view plain copy
- //修改Cookie对象有以下两种方式:
- //方式一:创建一个同名的Cookie对象
- //Cookie cookie = new Cookie("username", "meihouwang");
- //response.addCookie(cookie);
- //方式二:修改Cookie的value值
- Cookie[] cookies = request.getCookies();
- if(cookies != null){
- for (Cookie cookie : cookies) {
- String name = cookie.getName();
- if("username".equals(name)){
- cookie.setValue("qitiandasheng");
- //将修改之后的Cookie对象发送给浏览器
- response.addCookie(cookie);
- }
- }
- }
持久化Cookie对象
[java] view plain copy
- //创建一个Cookie对象
- Cookie cookie = new Cookie("user", "admin");
- //持久化Cookie对象
- /*
- * 通过setMaxAge(int age)方法来持久化Cookie对象
- * age > 0 :在age秒后Cookie对象失效
- * age = 0 :Cookie对象立即失效
- * age < 0 :会话级别的Cookie对象,默认
- */
- //设置Cookie对象7天内有效
- //cookie.setMaxAge(60*60*24*7);
- cookie.setMaxAge(-9);
- //将Cookie对象发送给浏览器
- response.addCookie(cookie);
Cookie对象的有效路径:
不是访问任何路径都会携带所有的Cookie对象
Cookie的有效路径即访问那些路径时会携带该对象,默认的有效路径是当前Web应用的根目录,我们还可以通过setPath()方法设置Cookie对象的有效路径
[java] view plain copy
- //创建一个Cookie对象
- Cookie cookie = new Cookie("user2", "admin2");
- //设置Cookie对象的有效路径
- //setPath()中的路径由浏览器解析
- cookie.setPath("/Web07_Cookie/hello");
- response.addCookie(cookie);
Cookie对象的用途:
广告推送
免登录
Cookie的缺陷:
Cookie对象是明文的,不安全
不同的浏览器对Cookie对象的大小和个数有限制
Cookie对象过多耗费流量
所以就出现了Session
3.Session
Session即我们非常熟悉的HttpSession,用来保存用户信息
Session的运行机制
1)在服务器端创建一个Session对象,该对象有一个全球唯一的ID
2)在服务器端创建Session对象的同时还会创建一个name为一个固定值JSESSIONID的Cookie对象并发送给浏览器,而且这个特殊的Cookie对象的value值就是Session对象的ID
3)以后浏览器发送请求时会携带name为JSESSIONID的Cookie对象,服务器会根据Cookie对象的value值来验证是否有对应的Session对象
4)服务器根据name为JSESSIONID的Cookie对象来区分不同的用户
Session对象的创建
[java] view plain copy
- Session对象在Servlet中通过request获取,只有获取了Session对象才会设置对应的name为JSESSIONID的Cookie对象
- //获取Session对象
- HttpSession session = request.getSession();
- //获取session对象的id
- String id = session.getId();
- System.out.println(id);
通过持久化JSESSIONID的Cookie对象来保持Session对象
当我们关闭浏览器时,由于Cookie默认是会话级别的,所以JSESSIONID对应的Cookie对象失效,再次打开浏览器时就不能找到之前创建的Session对象,我们可以通过将JSESSIONID的Cookie对象持久化的方法找到之前的Session对象
[java] view plain copy
- //获取ookie对象
- Cookie[] cookies = request.getCookies();
- if(cookies != null){
- for (Cookie cookie : cookies) {
- //获取cookie的name
- String name = cookie.getName();
- if("JSESSIONID".equals(name)){
- //持久化该Cookie对象
- cookie.setMaxAge(60);
- //发送给浏览器
- response.addCookie(cookie);
- }
- }
- }
设置Session对象的最大空闲时间
Session对象的默认最大空闲时间是30分钟,我们还可以设置它的最大空闲时间
[java] view plain copy
- //获取Session对象
- HttpSession session = request.getSession();
- //设置Session对象的最大空闲时间
- /*
- * 可以通过setMaxInactiveInterval(int age)来设置Session对象的最大空闲时间
- * age > 0 : 在age秒后Session对象失效
- * age = 0 : Session对象立即失效
- * age < 0 : Session对象永远不失效
- *
- */
- session.setMaxInactiveInterval(-8);
- //我们通常使用下面的方法设置Session对象立即失效
- session.invalidate();
钝化与活化:
钝化:Session对象及session域中的属性从内存中序列化到硬盘上的过程
活化:Session对象及session域中的属性从硬盘上反序列化到内存中的过程
要保证Session域中的属性可以被钝化和活化Session域中的属性必须实现Serializable接口
URL重写
在浏览器禁用Cookie的情况下,每次发请求无法携带Cookie对象,就导致无法找到之前创建的Session对象,这种情况下就可以通过URL重写将JSESSIONID通过参数的形式发送到服务器,从而找到对应的Session对象
URL重写有以下方式
[java] view plain copy
- <%
- //通过response的两个方法
- String url = response.encodeURL(request.getContextPath()+"/login.jsp");
- String url2 = response.encodeRedirectURL(request.getContextPath()+"/login.jsp");
- %>
- <!-- 通过标签 -->
- <c:url value="/login.jsp"></c:url>
二、表单的重复提交
同一个表单,同样的内容向服务器提交多次
表单重复提交的危害:
增加服务器的压力数据库中会保存很多垃圾数据
表单重复提交主要有以下三种情况:
1)在转发的情况下:表单提交成功之后反复刷新成功页面
产生的原因:在转发的情况下,地址栏没有变化,刷新成功页面相当于重复向form表单中的action属性值重复提交请求
解决方案:使用重定向
2)在网速很慢的情况下:反复点击提交按钮
产生的原因:提交按钮可以被点击多次
解决方案:让提交按钮只能点击一次
3)表单提交成功之后,点击返回(回退)按钮,在不刷新页面的情况下再一次提交表单
产生的原因:服务器会处理重复提交的请求
解决方案:使用token(记号)来判断是否是重复提交的请求
使用token的流程
①在服务器端使用UUID生成一个全球唯一的字符串(token),然后将它放到session域中
②将全球唯一的token放到表单的隐藏域中,随着表单一起提交到服务器
③在服务器端获取表单隐藏域中的token,然后session域中的token进行对比,如果相等:正常处理请求,不相等:即为重复提交请求。
④将session域中的token移除