会话技术
1) 概述
会话
对于java的概念:
当打开浏览器,意味着会话开始了
浏览器和服务器可以进行N多交互
当关闭浏览器,意味着会话结束了
作用
会话技术的作用:用来储存会话过程中,浏览器和服务器进行交互产生的N多数据的
会话技术的分类:
1 cookie(客户端会话):cookie用来存浏览器和服务器进行交互产生的N多数据的 将cookie放入浏览器中保存
2 session(服务端会话) session用来存浏览器和服务器进行交互产生的N多数据的 将session放入服务器中保存
问:什么情况下我们会选择使用cookie或session去存储浏览器和服务器交互中产生的数据?
当用户有私人数据需要在多个servlet之间进行传递的时候,可以选择使用会话技术(cookie和session)
客户端的会话技术:cookie
概述
cookie: 小纸条
作用:存储数据进行传递的
特点
1 小纸条(整个cookie)在浏览器上保存
2 小纸条由服务器端创建给浏览端保存的
cookie的使用
1 服务器如何创建cookie
Cookie cookie=new Cookie(String,String);
PS:key和value都得是字符串类型
2 服务器如果把cookie传递给客户端
response.addCookie(cookie);
注意:服务器可以给浏览器传递多个cookie,浏览器都会保存 但存在key值覆盖
3 服务器端如何获取到浏览器传递的cookie信息
Cookie[] request.getCookies(); //自动从请求头中 获取cookie信息 并且切割并封装成多个cookie对象
cookie的常用API
getName(); 返回值String,返回的是cookie的key
getValue(); 返回值String,返回的是cookie的value
cookie的整个使用过程
完成私人数据在多个servlet之间进行数据传递:
服务器创建cookie存储数据--->把整个cookie传递给浏览器---->浏览器端自动保存cookie(key值覆盖)
浏览器会自动将保存的cookie传递服务器资源--->服务器获取传递的cookie数据--->使用cookie数据
cookie的细节
会话级别的cookie(默认方式)和持久化级别的cookie
会话级别的cookie:浏览器关闭当前会话默认会把保存的cookie全部销毁(默认)
持久化级别的cookie:可以让浏览器在一定时间不论开关都会保留cookie 但是有效期已过,浏览器立马清除cookie
方法:setMaxAge(秒)
>0: 有效时间
=0:过期(清除)
特点:设置的时间如果到期了,浏览器会自动把过期的cookie销毁
cookie的路径:通过设置cookie的路径 设置该cookie在哪些资源下有效
方法api:setPath(“路径”)
/项目名/资源名 只在访问/day10/cs5资源才带
/项目名 访问整个day10项目下的资源都带(企业)
/ 访问整个服务器上的项目资源都带
默认 当前servlet访问路径的上一级
访问到当前servlet的上一级路径才带
例如:Servlet: /demo/sd1==访问/demo下的资源才携带
cookie的注意点:
cookie中不能出现特殊符号 例如:空格 分号 逗号
cookie存入的数据有大小限制 只能存字符串 大小不能4kb
案例:记录用户最新访问时间 且输出用户的上次访问时间
需求:展示用户最后一次访问的时间
代码实现
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//响应内容的中文编码问题解决
response.setContentType("text/html;charset=utf-8");
// 记录当前用户的访问时间
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String time = format.format(new Date());
time=URLEncoder.encode(time,"utf-8");
System.out.println(time);
Cookie cookie = new Cookie("time",time);
cookie.setMaxAge(60*60*24); //设置cookie的持久化时间(1天)
cookie.setPath(request.getContextPath()); //访问我们当前项目下的资源都能得到cookie
response.addCookie(cookie);
// 输出用户的上次访问时间(上次没访问过 就输出没访问过)
Cookie[] cookies = request.getCookies();
if(cookies!=null){
for (Cookie ck : cookies) {
if(ck.getName().equals("time")){
String value = ck.getValue();
value=URLDecoder.decode(value,"utf-8");
response.getWriter().print("该用户的上次访问时间是:"+value);
return;
}
}
}
response.getWriter().print("该用户之前没有访问记录...");
}
服务器端的会话技术:session
概述
session是保存在服务器端的会话技术
作用:也是为了保存会话中产生的数据
特点
1 保存在session中的数据在服务器端。由服务器创建的
2 session其实就是一个域对象 xxxAttribute()存储数据的方法
session的使用
session获取:request.getSession()
作用范围:
session中的数据在一次会话中共用
因为在一次会话中,访问多少个servlet,获取到的session都是同一个
但是如果不在一次会话中,多个servlet中产生的不再是同一个session对象
session的剖析(理解)
为什么在一次会话中,使用的都是同一个session对象
Cookie:JSESSIONID=C573A3AF2DDF0491AE6FB31608525641
因为jsessionid相同,根据jsessionid获取的session是同一个
为什么浏览器关闭以后(不在一个会话了),使用的就不是同一个对象了
浏览器一关闭 Cookie销毁了 cookie中的JSESSIONID也就没有
session的执行流程
当执行到调用getSession方法时,首先判断cookie中是否有jsessionid。
如果不存在jsessionid:那么直接创建一个新的session对象返回给你,并且向响应头中写一个新的jsessionid存放cookie给浏览器保存
如果存在jsessionid:从服务器内存中去获取对应的session对象继续使用
(浏览器关闭)
再次判断cookie中是否有jsessionid,如果没有,那么直接创建一个新的session对象返回给你,并且向响应头中写一个新的jsessionid存放cookie给浏览器
session和cookie的区别?(面试题)
session:服务器端的会话技术 数据都在服务器
cookie:客户端的会话技术 数据都在浏览器
session:存储的内容没有大小限制
cookie:只能存储4kb的内容
session:存储的数据安全
cookie:存储的数据不安全
伪登录案例
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<h2>用户登录</h2>
<form action="/login" method="post">
用户名:<input type="text" name="username"><br/>
密码:<input type="password" name="password"><br/>
验证码:<input type="text" name="yzm" size="6px">
<img id="imgs" src="/sd8"> <br/>
<input type="submit" value="提交">
</form>
<script>
//1 获取img标签
let img=document.getElementById("imgs");
//2 做一个点击事件
img.onclick=function(){
//3事件触发 让/sd8再执行一次 返回一个新的验证码
img.src="/sd8?time="+new Date();
}
</script>
</body>
</html>
package com.itheima.web;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet(name = "LoginServlet",urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
//1 验证用户填写的验证码是否正确
//不正确:结束程序 给用户提示信息
//1.1 先获取用户填写的验证码
String yzm = request.getParameter("yzm");
//1.2 获取图中的验证码(servletDemo8) --从session中取验证码
HttpSession session = request.getSession();
String imgYzm =(String)session.getAttribute("imgYzm");
System.out.println("用户输入的验证码是:"+yzm+",图片中的验证码是:"+imgYzm);
//1.3 判断
if(yzm==null || !yzm.equalsIgnoreCase(imgYzm)){
//验证码不匹配
response.getWriter().print("你的验证码输入有误,请重新输入...");
return; //结束下面的程序
}else{
//2 正确:获取用户名和密码做匹配
// 匹配成功:登录成功
// 匹配不成功:登录失败
String username = request.getParameter("username");
String password = request.getParameter("password");
/** 用数据库替换掉 **/
if(username==null || !"jack".equals(username)){
response.getWriter().print("用户名输入有误,请重新输入...");
return;
}
if(password==null || !"888888".equals(password)){
response.getWriter().print("密码输入有误,请重新输入...");
return;
}
/** 用数据库替换掉 **/
response.getWriter().print("欢迎你的登录:"+username+"用户");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
域对象的总结(重点)
哪些技术可以在多个servlet/jsp之间进行数据传递: ServletContext request 会话技术(cookie session)
域对象:java后台的域对象有3个: ServletContext request session
特点:xxxAttribute方法
总结数据作用范围:
Request
创建: 请求一次 创建一次
销毁: 响应一次 销毁一次
存入数据的作用范围:一次请求,多次转发的servlet可以共用数据
原因:一次请求中,涉及到的多个servlet中的request对象是同一个
ServletContext 公共数据
创建:服务器启动就创建 且还有一个
销毁: 服务器关闭就销毁
存入数据的作用范围:整个项目下的所有servlet都可以共用数据
原因:因为一个项目只有一个servletContext对象
Session 私有数据(cookie)
创建: 第一次请求执行request.getSession方法的时候创建session对象
销毁: 3种
被动销毁 30封装未使用 销毁
主动销毁 session.invalidate()
服务器非正常关闭,服务器正常关闭不销毁
存入数据的作用范围:一次会话中 多个servlet都可以共用数据
原因:一次会话,多个serlvet使用的是同一个session对象 (基于cookie(jsid))
注意:只要多个servlet/jsp之间做数据传递和共享了,都要想到以上域对象