目录
我们这次主要体现Cookie和 Session应用在登录页面的体现。
🚩本章目标
1.登录页面
发起一个http请求,触发登录逻辑(带上用户输入的用户名和密码)
2.servlet处理上述的登录请求
通过这个servlet读取用户名和密码,并且验证是否登录成功
如果登录成功,就会给当前这个用户,创建一个会话(这个会话就存储了用户当前的信息),并且把得到的sessionId,通过cookie给客户端(客户端把cookie存储起来)
3.网站主页(成功登录之后的页面)
在这个页面中,就会把刚才的用户数据据给显示在页面上,比如使用“张三”用户来登录,主页上就会显示,“欢迎你张三”这个标识。
🚩实现过程
🎓登录页面
此处预期发送的请求
POST login
Content-Type:application/x-www-form-urlencoded
(使用form表单,Content-Yype就是这个格式)此处的登录,使用json也不是不可以,使用json就无法使用form表单了(使用json就需要通过ajax的方式构造请求)
username=zhangsan&password=123
插一句:浏览器构造http请求,就几种方式
- url输入地址(GET)
- 特殊的html标签 a,img,script(GET)
- form表单(GET,POST)
- ajax(GET,POST,PUT,DELETE......)
🎓Servlet处理登录请求
🎈获取请求传来的参数(用户名和密码)
1.获取请求getParameter方法,来获取请求传来的参数(用户名和密码),但是我们最好先给请求设置一个字符集,否则如果username是中文,getParameter可能会乱码。
req.setCharacterEncoding("utf8");
String username=req.getParameter("username");//zhangsan
String password=req.getParameter("password");//123
🎈验证密码是否正确
2.验证用户名密码,是否是正确的,一般来说,验证用户名密码,是要通过数据库的
此处为了简单一点,先把用户名和密码,写死,比如此处假设正确的用户名是“zhangsan",正确的密码是123.
此处还要注意,上述getParameter可能会拿到null,为了避免空指针,下面的这种比较更合适的。
1.上一种如果先看看username是否为空,如果username为空,那么就会抛出空指针异常。
2.下面一种方式,就是看看"zhangsan"是不是和username相对应,如果不等于,就直接给 用户返回一个提示,提示之前要给返回的响应设置字符集,防止返回的提示是中文显示乱码。equals内部能够针对参数为null做好处理
if(!"zhangsan".equals(username) || !"123".equals(password)){ //登录失败,给用户返回一个提示 resp.setContentType("text/html; charset=utf8"); resp.getWriter().write("当前的用户名或者密码错误"); }
📝不同场景设置字符集
显示在页面上设置字符集
resp.setContentType("text/html; charset=utf8");
客户端传来的参数设置字符集
req.setCharacterEncoding("utf8");
🎈登录成功,创建会话
登录成功了,给这个用户创建会话也就是用到session,我们可以给会话中保存一些自定义的数据,通过Attribute的方式来保存。
//3.登录成功了,给这个用户创建一个会话出来
//可以给会话中保存一些自定义的数据,通过Attribute的方式来保存
HttpSession session=req.getSession(true);
//此处Attribute也是键值对,这里的内容存储什么都可以,程序员自定义
//这样的数据存储了之后,后续跳转到其他页面,也随时可以把这个数据从会话中取出来
session.setAttribute("username",username);
session.setAttribute("loginTime",System.currentTimeMillis());
//此时相当于登录成功了,让页面跳转到网站首页
resp.sendRedirect("index");
我们看到
HttpSession session=req.getSession(true);
true参数就是允许在不存在时自动创建,参数为false不能创建,直接返回null
getSession这个方法,就是根据请求的cookie中的sessionId,查询服务器的hash表。找到对应的session对象,如果cookie中没有sessionId(首次登录的时候,就是没有的)或者sessionId没有查到对应的session对象,就可以创建出一个session对象出来。
会创建出一个sessionId和一个session对象,把这个键值对保存到hash表中,并且会把sessionId设置到响应中(响应报头中加上Set-Cookie字段),传回给浏览器,让浏览器使用Cookie来保存。
session.setAttribute("username",username); session.setAttribute("loginTime",System.currentTimeMillis());
这里使用Attribute的作用,主要就是为了让一个数据,在多个Servlet之间共享,同时Attribute时会话级别的,每个用户/客户端都是有自己的数据,相互之间都不会有干扰的。
- 如果这个servlet时通过第一个浏览器(sessionId_身份标识)调用的,此时Servlet里面拿到的就是zhangsan这个Session对象,及其里面的数据
- 如果这个servlet是通过第二个浏览器(sessionId_身份标识)调用的,此时servlet里面拿到的就是lisi这个Session对象,及其里面的数据。
通过sessionId取会话对象(两个浏览器,sessionId不同)
同样的页面,不同用户看到的数据肯定是不同的,支付宝,就有查看资产页面,我访问这个页面,看到的数据,和码云爸爸访问这个页面,看到的数据,肯定是不相同的。
🎈跳转网站首页
//此时相当于登录成功了,让页面跳转到网站首页resp.sendRedirect("index");
重定向跳转到index页面上(后续会写一个Servlet生成这个页面)
🎓实现登录后的主页
🎈获取当前用户对应会话对象
//1.先获取到当前用户对应的会话对象,生成的页面要根据当前用户信息来构造
HttpSession session=req.getSession(false);
if(session==null){
//sessionId不存在,或者sessionId没有在hash表中查到
resp.setContentType("text/html;charset=utf8");
resp.getWriter().write("你当前未登录!");
return;
}
根据cookie中的sessionId来查询Servlet这里的hash表,参数设置成false,如果查到了,就直接返回,没查到,就返回null。
会话,就可以理解成”用户身份信息“体现,在通过登录操作,验证了用户身份之后,才能够创建会话。其他页面,没有做”验证身份“,不应该创建会话。
getsession(false) 操作内部拿着sessionId来查询的,同一个SessionId(同一个cookie等同于同一个浏览器),就能拿到同一个session对象。
如果没有查到对应的session对象,那么就显示给客户端表示未登录。
🎈查找到了后从会话中拿到存储的用户信息
//2.从会话中拿到之前存储的用户信息
//此处的强转,需要程序员自行保证,类型是靠谱的
String username=(String) session.getAttribute("username");
Long loginTime=(Long)session.getAttribute("loginTime");
但是sessionId能区分到对应的session对象,查到对应的用户名和登录时间信息 。
🎈生成页面,显示数据到页面上
//3.生成一个页面,把上述数据显示到页面上
resp.setContentType("text/html; charset=utf8");
String respBody="欢迎您"+username+"! 上次登录时间为: "+loginTime;
resp.getWriter().write(respBody);
得到的结果是Object,存的时候,各种数据都可以存。
🚩fidder抓包检验
📝点击登录之后就会触发一个POST请求
📝服务器
此处getSession会创建新会话
- 1.生成sessionId和HttpSession对象
- 2.把上述sessionId和HttpSession对象保存到内存hash表中
- 3.把sessionId设置到响应报文的header中set-Cookie字段
JSESSIONID这个key是固定的,就叫做JSESSIONID(从更广义的概念上属于是sessionId)
后面一串数字,每个客户端都不同。
浏览器拿到响应,就会把这个Set-Cookie的内容保存到浏览器的Cookie中
- key:JSESSIONID
- value:
保存,就是为了后面再次访问服务器的时候,能够带上这个cookie
📝重定向到主页(index)
拿着JSESSIONID这里的数值,查询hash表,拿到刚才创建的session对象。(这个JSESSIONID就是身份标识)
📝总思路
🚩总结
浏览器首次访问登录操作的时候,就会在服务器这边验证身份,验证通过,就会创建会话。服务器就会保存会话信息(hash),客户端也会保存身份标识(sessionID).后续浏览器再次访问这个网站(网站的其他页面)都会带上cookie(sessionId),服务器就不需要让浏览器重新登录,也能识别出浏览器的用户身份信息。
一个网站只要登录成功之后,后续访问这个网站的其他页面,也都是会处在一个登陆的状态,上述过程中都是可以借助cookie和session来完成的。
i人小突破!本人风格:先做再说。