会话
会话: 当浏览器打开,访问到服务器 表示会话开始
会话进行中: 浏览器和服务器之间进行通信(一次通信 多次通信)
会话结束:当浏览器关闭 , 会话结束
会话的问题:会话中产生的数据 需要保存
会话指的是浏览器和服务器之间交互的一个过程, 会话中必然会产生数据,有效数据和无效数据, 有效数据可能需要保存 , 保存的位置内存, 硬盘. 我们可以存在浏览器端 或者 服务器端
会话技术
会话技术:
作用:保存数据
浏览器端的技术: cookie
服务器端的技术: session
cookie
会话级别cookie
OneServlet
public class OneServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("OneServlet");
//1.有数据需要保存 创建cookie
Cookie cookie = new Cookie("ds" , "meimei");
//2.将cookie响应给浏览器
response.addCookie( cookie );
}
}
TwoServlet
public class TwoServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("TwoServlet");
//拿到浏览器传递的cookie
Cookie[] cookies = request.getCookies();
//对数组进行遍历
//此请求中包含的所有 Cookie 的数组,如果该请求没有 cookie,则返回 null
if(cookies != null ){
//遍历cookie
//Idea-a04ab689 @@ b23c0a93-4c5e-4a7e-9125-9dbc273d9498
//这个是idea版本的问题 有的版本会产生一个cookie
for (Cookie cookie : cookies) {
//name 表示cookie的名称 value表示cookie的值
System.out.println( cookie.getName() +" @@ "+cookie.getValue() );
}
}else{
System.out.println("没有cookie数据");
}
}
}
小结:
默认浏览器关闭 cookie消失 , 会话级别的cookie , 会话结束 cookie失效了
Cookie cookie = new Cookie(name , value); 创建cookie
response.addCookie( cookie ); 响应cookie
Cookie[] cookies = request.getCookies(); 获得cookie
cookie是保存在浏览器上的 , 不同的浏览器 不能共享cookie
持久化级别cookie
cookie.setMaxAge( 时间 ); 设置cookie最大存活时间 单位秒
cookie.setPath( ) 设置路径
cookie细节部分
/**
* cookie的小细节:
* 1.cookie 不支持中文 , tomcat8处理过了 tomcat 7 没有处理 (不支持中文)
* 2.cookie 遵循423的规则(以前的老说法)
* 4表示4kb: cookie的长度不要过长 最大4kb(精准的)
* 2表示20个: 一个网站支持的最大cookie数量20个 (不精准)
* 3表示300个: 整个浏览器 所有的网站加起来的cookie 300个(不精准)
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("OneAPIServlet");
//1.有数据需要保存 创建cookie
Cookie cookie = new Cookie("ds" , "呵呵");
//设置cookie的属性
//设置cookie最大有效生存时间 单位:秒
cookie.setMaxAge( 0 );
/**
* 设置path路径
* path的含义是:
* 1.表示再次请求发送给服务器的时候 cookie自动携带的依据 必须满足 path 的目录或者path的子目录都可以
* path : localhost/day05
* localhost:8080/day05/a/b/c 资源 会自动携带cookie 子目录
* localhost:8080/day05/a 资源 会自动携带cookie 相同路径
* localhost:8080/day05/a/a.html 资源 会自动携带cookie 子目录
* localhost:8080/day06/a 资源 不会自动携带cookie 不符合路径
* www.baidu.com:8080/day06/a 资源 不会自动携带cookie 不符合路径
* 2.path 和 name 决定cookie是不是唯一的
* cookie在本地是可以重名的 只要放置的path路径不一样即可
* 小结:注意,以后设置路径的时候 一般建议 cookie.setPath("/"); 尽量不要携带项目名称
* 一个公司 十个项目 十个项目的cookie建议都是共享的
* 设置成 localhost/ 后续的项目 localhost/day05 localhost/day06 都可以访问这个cookie
*
* 问题1:如果覆盖cookie?
* name + path 必须跟之前的cookie对应
* 问题2:如何删除cookie?
* (name + path) 覆盖 + 时间(立即失效) 没有直接删除cookie的api
*/
cookie.setPath("/");
//2.将cookie响应给浏览器
response.addCookie( cookie );
}
记录上次访问时间
/**
* 输出用户的上次访问时间 , 记录用户的本次登录时间
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//防止乱码
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//1.判断用户到底是第一次访问还是第N次访问
//获得cookie
Cookie[] cookies = request.getCookies();
boolean flag = false; //默认就是false
String cookieValue = null;//定义一个cookie的值
if(cookies != null ){//第一次访问还是第N次访问 不代表第一次 也不代表第N次 不确定
//有其他的cookie 例如 ds 但不是lastTime
for (Cookie cookie : cookies) {
if( "lastTime".equals(cookie.getName()) ){//如果能进入if表示的是 有最后的时间 表示第N次访问
cookieValue = cookie.getValue();
flag=true;
}//else{//第一次访问? 假设 ds dzd username lastTime nickname
//}
}
}//else{//第一次访问 没有cookie意味着 没有 lastTime 第一次访问
//}
if(flag == true ){ //第N次访问
//3.第N次访问 输出您上次的访问时间为....
//拿到上次的访问时间
//拿到的结果是编码前的结果 必须还要解码
String decode = URLDecoder.decode(cookieValue, "utf-8");
System.out.println("您上一次访问时间为:"+ decode +" @@" +cookieValue );
//再次覆盖本地的时间 覆盖cookie条件是 : path + name 一模一样
String date = new Date().toLocaleString();//创建时间
String encode = URLEncoder.encode(date, "utf-8");// 编码
Cookie cookie = new Cookie("lastTime" , encode);
cookie.setMaxAge(60*60); //设置有效时间
cookie.setPath("/");//设置路径
response.addCookie( cookie );
}else{ // 第一次访问
//2.第一次访问 输出您是第一次访问即可
//报错:java.lang.IllegalArgumentException: An invalid character [32] was present in the Cookie value
//cookie不能支持所有的特殊符号 编码 : 将原本的字符修改成别的符号 要还原符号 解码即可
String date = new Date().toLocaleString();
//编码:采用URL编码 (jdk自带工具类)
//参数1:需要被编码的字符串 参数2: 以后解码的码表
String encode = URLEncoder.encode(date, "utf-8");
System.out.println("您是第一次访问编译前的时间:" +date + " @@ 编译后的时间:" +encode );
Cookie cookie = new Cookie("lastTime" , encode);
cookie.setMaxAge(60*60); //设置有效时间
cookie.setPath("/");//设置路径
response.addCookie( cookie );
}
}
Session
服务器端用session存储数据
session比cookie重要
session的底层是基于cookie的
session的原理说明
session默认使用的cookie是会话级别的cookie , 浏览器关闭 ,cookie过期 session丢失
将session转换成持久化级别的session , 使用持久化级别的cookie (在开发中 几乎没用过持久化级别session)
OneServlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("OneSessionServlet");
//获得session(第一次调用为创建)
HttpSession session = request.getSession();
System.out.println( "是不是新创建的:" + session.isNew() );
//System.out.println( "获得session的id:" + session.getId() );
//System.out.println( session );
session.setAttribute("ds" , "旺财");
}
TwoServlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("TwoSessionServlet");
HttpSession session = request.getSession();
System.out.println( "是不是新创建的:" + session.isNew() );
//System.out.println( "获得session的id:" + session.getId() );
//System.out.println( session );
Object ds = session.getAttribute("ds");
System.out.println("ds:" + ds );
}
session的一些小知识点
session的底层是基于cookie的, 如果cookie丢失 session还在不在?
session还在 , 只不过是因为cookie丢失 session找不到了
session可以找回来的.(能找回来)
URL重写, 对地址栏重新改造就可以找到session
可以对地址进行修改 拼接 ;jsessionid=id值 (固定写法)
如果浏览器 , 禁用cookie了 , session还能不能用?
能用
session是域对象 ,
cookie为什么不是域对象 ?
域对象的含义: 一定范围内可以保存数据的对象 称之为域对象
域对象指的是服务器的内部对象 而cookie属于浏览器端技术 .
web中的域对象 : request , session ,servletContext
cookie和session的区别
session :服务器端技术 , 数据保存在服务器(数据安全) , 数据的长度不限(取决于服务器的容量,不建议存储太大)
cookie : 浏览器端技术 , 数据保存在客户端(不安全) 数据的长度有限的 4kb
cookie和session的关系
session的生命周期
什么时候创建的: 第一次调用 request.getSession() 的时候创建
什么时候销毁的: 方式有三种
1.默认情况下tomcat超时三十分钟自动销毁
2.手动调用session的invalidate()方法进行销毁
3.服务器非正常关闭 (服务器正常关闭session还在)正常关闭 : 释放资源(将内存中的session对象 保存在了本地 当下一次服务器启动的时候 加载到内存 )
非正常关闭 : 断电 . 强制关闭 (让我们的服务器来不及释放资源即可)
域对象总结
web中的域对象 : request , session ,servletContext
域对象:对象在生存的有效时间段内 可以共享数据
request: 一次请求中 多个资源可以共享数据
创建:浏览器发起请求就创建
销毁:响应回去就销毁
session: 一次会话中(浏览器打开访问服务器,只要浏览器不关闭) 所有的请求(共享同一个session) 共享数据
创建: 第一次调用request.getSession()创建
销毁: tomcat超时三十分钟, 手动销毁, 服务器非正常关闭销毁
servletContext: 一个项目中 , 多次会话 , 多次请求, 共享同一份数据
创建: 服务器启动就创建
销毁: 服务器关闭就销毁
域对象的选择:
1. 能小不大原则 (时效性的问题)
2. 需求优先原则(项目的字符集编码)