JavaWeb初级学习 之 会话控制&表单重复提交问题

一、会话控制


1.为什么会出现会话控制


HTTP协议的特点:

纯文本
无状态
浏览器不能区分多个请求是否来自同一个用户
但是有时候我们需要让浏览器知道多个请求来自同一个用户,比如:网上购物。所以就出现了会话控制
会话控制涉及到两种技术
Cookie
Session

2.Cookie

Cookie就是服务器发送给浏览器的用于区分不同用户的一段信息

Cookie的运行机制
1)服务器创建一个Cookie对象
2)服务器将Cookie对象发送给浏览器
3)以后浏览器发请求就会携带着该Cookie对象
4)服务器根据Cookie对象来区分不同的用户

创建Cookie对象
//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对象
//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对象
//修改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对象
//创建一个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对象的有效路径
//创建一个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对象的创建
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对象
//获取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分钟,我们还可以设置它的最大空闲时间
//获取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重写有以下方式
<%     
	//通过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移除





  • 2
    点赞
  • 1
    收藏
  • 打赏
    打赏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:技术黑板 设计师:CSDN官方博客 返回首页
评论

打赏作者

OnlyLove_longshao

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

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值