12.会话技术

今天我们了解两个会话技术
1.cookie技术
2.session技术

会话技术
1.会话:一次会话中包含多次请求和响应
2.一次会话:浏览器第一次给服务器资源发送请求开始,会话建立,直到有一方断开为止,(浏览器或者是服务器)
3.功能:共享数据,在一次会话的范围内的多次请求间,共享数据
4.方式:(其他语言中可能也存在会话技术,但是不一定是这么取名字)
1.客户端会话技术cookie (把数据存放在客户端浏览器中)
2.服务器端会话技术 session(把数据存放在服务器端)


cookie会话技术

1.概念:客户端会话技术将数据保存在客户端
2.原理:cookie是基于请求头cookie和响应头set-cookie的实现
图解:


实现原理
  • 1.快速入门

1.创建cookie对象,设置数据

 Cookie cookie =new Cookie("username","xzw");

2.发送cookie对象

 response.addCookie(cookie);

3.获取cookie对象数组

Cookie[] cookies = request.getCookies();
//demo1
@WebServlet("/cookieServletDemo1")
public class CookieServletDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.创建cookie
        Cookie cookie =new Cookie("username","xzw");
        //2.发送cookie
        response.addCookie(cookie);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}
//demo2
@WebServlet("/cookieServletDemo2")
public class CookieServletDemo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //3.获取Cookie,拿到里面的数据
        Cookie[] cookies = request.getCookies();
        if (cookies!=null){
            for (Cookie c : cookies) {
                String name = c.getName();
                String value = c.getValue();
                System.out.println(name+":"+value);
            }
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

抓包:

  • 在第一次请求响应时,请求体中没有内容,而在响应体中有set-cookie


    第一次请求/响应
  • 在下一次请求的时候,请求体中cookie中有cookie存储的内容,而在响应体中没有内容


    在下一次请求/响应中
  • 总结:就是通过响应头和请求头实现了cookie中多次请求之间共享数据

  • 2.cookie会话技术中的细节和API

1.一次可以发多个cookie,创建多个cookie对象,使用reponse对象进行发送
方法:

response.addCookie(Cookie cookie);
@WebServlet("/cookieServletDemo3")
public class CookieServletDemo3 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //创建对个Cookie对象
        Cookie cookie1 = new Cookie("mag1","1");
        Cookie cookie2 = new Cookie("mag2","3");
        //使用response对象对其进行发送
        response.addCookie(cookie1);
        response.addCookie(cookie2);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

在demo中获取可以获取两个值

请求头响应头

思考:使用相同的cookie名字,是创建一个新的cookie还是覆盖?
答案是会覆盖

/**
 * 发送多个Cookie对象
 */
@WebServlet("/cookieServletDemo3")
public class CookieServletDemo3 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //创建对个Cookie对象
        Cookie cookie1 = new Cookie("mag1","1");
        Cookie cookie2 = new Cookie("mag1","3");
        //使用response对象对其进行发送
        response.addCookie(cookie1);
        response.addCookie(cookie2);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}
下一次请求/响应

2.cookie在浏览器中能保存多长时间
1,默认情况下,浏览器关闭的时候,cookie数据会被销毁(存储在浏览器的内存中)
2,我们可以设置cookie的生命周期,让cookie持久化存储(储存在硬盘中)
方法:

setMaxAge(int seconds);//参数是秒

方法参数:
1.正数,将cookie数据写在磁盘中(持久化),参数是持久化时间,以秒为单位
2.负数,默认值(浏览器关闭之后,cookie数据就会消失)
3.0,删除cookie数据
我们可以通过这个函数来设置cookie的存活时间
默认关闭浏览器之后就会消失

@WebServlet("/cookieServletDemo4")
public class CookieServletDemo4 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.创建一个cookie对象并绑定数据
        Cookie cookie = new Cookie("time","12");
        //1.1设置cookie在浏览器中的保存时间
        //cookie.setMaxAge(-1);//默认关闭浏览器就会消除
        // cookie.setMaxAge(300);//将cookie数据持久化纯真,300秒后删除
        cookie.setMaxAge(0);//直接删除cookie信息
        //2.发送数据到客户端
        response.addCookie(cookie);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

3.cookie能不能存放中文字符呢?
在tomcat8以前是无法存放中文字符的
解决方法是:需要将中文数据进行URL编解码
在tomcat8之后可以存放中文字但是无法存放特殊字符
!我们以后再做项目的时候可能由于很多原因不会使用tomcat8以上的版本,我们这个时候可以对其进行URL编解码操作
方法:
编码:
URLEecoder.encode("字符串","字符编码");
解码
URLDecoder.decode("字符串","字符编码")
用tomcat8以上的版本存放空格时,会出错
编码:

@WebServlet("/cookieServletDemo5")
public class CookieServletDemo5 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //创建cookie对象并绑定数据
        Cookie cookie = new Cookie("msg","谢子威真的傻逼 哈哈");
        //发送cookie数据到服务器
        response.addCookie(cookie);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

错误信息:


错误信息

这个时候我们需要对其进行URL编解码操作
如:

/**
 * 使用cookie存储中文数据,或者是特殊字符的时候
 */
@WebServlet("/cookieServletDemo5")
public class CookieServletDemo5 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String str ="谢子威真的傻逼 哈哈";
        System.out.println("编码前"+str);
        //进行URL编码
        str = URLEncoder.encode(str, "utf-8");
        System.out.println("编码后"+str);
        //创建cookie对象并绑定数据
        Cookie cookie = new Cookie("msgss",str);
        //发送cookie数据到服务器
        response.addCookie(cookie);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

这样就可以获取正确的结果


控制台信息

4.cookie的共享问题
1,假设在一个tomcat服务器中部署了多个项目,那么这些项目能否共享Cookie数据?
答案,默认情况下是不可以的,但是我们可以通过方法去修改cookie的范围
在官方文档中的解释是,为客户端应该返回的cookie指定一个路径。
真正的含义就是指定cookie的作用范围,默认情况下是当前项目的虚拟路劲,所以默认情况下是不在多个项目中共享的。
如果要共享,可以将Path参数设置成"/"(代表当前目录的根目录),这样的话cookie信息就会对服务器中的所有项目共享了
方法:

cookie.setPath(String path)

案例:

/**项目一中
 * 存储Cookie值,在其余的项目中观察是否能够获取
 */
@WebServlet("/cookieServletDemo6")
public class CookieServletDemo6 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //创建cookie对象,绑定数据
        Cookie cookie = new Cookie("massage","Idea22");
        //设置cookie数据在同一个tomcat下不同项目之间的作用范文
        cookie.setPath("/");
        //发送cookie数据到客户端
        response.addCookie(cookie);

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

/**项目二
 * 获取上一个项目中发送给浏览器的cookie值
 */
@WebServlet("/cookieServletTest")
public class CookieServletTest extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       //获取所有的cookie信息
        Cookie[] cookies = request.getCookies();
        for (Cookie c : cookies) {
            String name = c.getName();
            String value = c.getValue();
            System.out.println(name+":"+value);
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

获取成功,这默认情况下,也就是说不指定的情况下是没有这个效果的

控制台

2,在不同的tomcat服务器之下,cookie数据能否共享?
答案,也是可以的,但是我们要设置不同的服务器的一级域名是相同的,那么多个服务器之间的cookie是可以共享的
方法:参数path是域名

cookie.setDomain(String path)

如在百度中,百度贴吧,和百度新闻两个服务器之间如果想要共享cookie数据可以这么写

cookie.setDomain(".baidu.com");

这么写之后,tieba.baidu.com和news.baidu.com之间可以共享到cookie数据

这个我们以后再项目中会遇到。我们在去了解,我们看看官方文档怎么解释这一个方法
官方解释:指定应该在其中显示此cookie的域。

  • 3.cookie会话技术的特点
    1,cookie将数据存放在客户端浏览器
    2,浏览器对单个cookie的大小有限制(一般是4k),以及同一个域名下的中cookie数量有限制(一般是20个)
    相对不安全,不能存放大量数据,并且只能存储String数据
    作用:
    1.cookie一般用于存储少量不太敏感的数据
    2.在不登录的情况下,完成服务器对客户端的身份识别(很常用)
    如:保存我当前没有登录的情况下,对页面的一些设置,我下次在访问的时候,服务器会在通过存放的cookie来设置我页面的设置

session会话技术

1.概念:服务器端会话技术,将数据保存在服务器端
在一个会话的多次请求间共享数据,将数据保存在服务器端
2.原理:session的实现依赖于cookie

图解:


图解
  • 1.快速入门

1,获取Session对象,我们实际上使用的是HttpSession对象,它是一个域对象

HttpSession session = request.getSession();

2,使用HttpSession对象,使用域对象的常规方法

//1.通过指定的名称获取对应的值
object    getAttribute(String name);
//2.存储指定值
void       setAttribute(String name ,object value);
//3.删除指定Session对象
void       removeAttribute(String name);

代码演示:

//demo1
@WebServlet("/httpSessionDemo1")
public class HttpSessionDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.创建session对象
        HttpSession session = request.getSession();
        //2.将数据存储在session域对象之中
        session.setAttribute("username","xzw");

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}
//demo2
@WebServlet("/httpSessionDemo2")
public class HttpSessionDemo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.创建Session对象
        HttpSession session = request.getSession();
        //2.获取Session对象中的username值
        String username = (String) session.getAttribute("username");
        System.out.println(username);

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}
控制台中获取到数据

抓包:
第一次的响应体中set-cookie响应头信息,携带着set-cookie:JSESSION=ID属性值的信息


第一次请求/响应

下一次的请求头中Cookie头携带着Cookie:JSESSION=ID属性值的信息


下次请求/响应

注意观察这两个属性ID值是一样的,这就是在原理中,实现所有的资源创建的Session对象都是同一个对象的原因


  • 2.Session域对象使用细节
    1.当客户端浏览器关闭,服务器不关闭,两次获取的Session对象是不是同一个?
    答案:很显然,默认情况下不是的,这都不是一个会话之间的请求,但是我们可以使用编程的方法,让他们是相同的
    方法:我们通过原理可知,我们让所有获取的session对象相同的方法是通过cookie实现的,那么我们可以使用cookie持久化的方法让Session对象获取
    相同
    编程思想:
    1.创建Cookie对象,设置他的键值对为JSESSION和对应的ID属性值
    2.设置Cookie的最大存活时间,让cookie吃持久化保存
//demo3
@WebServlet("/httpSessionDemo3")
public class HttpSessionDemo3 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.创建Session对象
        HttpSession session = request.getSession();
        //2.创建Cookie对象
        Cookie cookie = new Cookie("JSESSION",session.getId());
        //3.设置cookie对象的最大存活时间
        cookie.setMaxAge(60*10);
        //4.打印Session的id属性值
        System.out.println("demo3:"+session.getId());

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}
//demo4
@WebServlet("/httpSessionDemo4")
public class HttpSessionDemo4 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.创建Session对象
        HttpSession session = request.getSession();
        //2.打印Session对象的ID属性
        System.out.println("demo4:"+session.getId());

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }
}

关闭浏览器之后访问,可以获取相同的Session对象,说明这种方法可以在浏览器关闭之后获取同一个Session对象,可以获取Session对象中的数据
控制台:


浏览器关闭之后,Session对象获取的是一样的

2.客户端不关闭,但是服务器端关闭,两次获取的Session对象是同一个吗?
答案:当然不是同一个,在服务器关闭之后Session对象会销毁,再次创建的Session对象和以前的肯定是不同的,但是要是这样的话,我们的项目就会出现很多问题,所以我们要确保数据不丢失,我们是怎么解决这个问题的呢?
虽然对象不是同一个,但是我们可以确保数据是同一个
解决方法
Session对象的钝化:在服务器关闭之前,将Session对象序列化到硬盘。
Session对象的活化:在服务器启动之后,将Session文件转化成内存中的Session对象即可。
Tomcat服务器自动为我们把这件事给做了,但是IDEA并不能完成这件事,IDEA可以钝化,但是活化不成功,但是无所谓,将来我们配置项目都是配置在Tomcat服务器之中


3.Session的失效时间(Session对象什么时候被销毁)?
1,服务器关闭
2,Session对象调用invalidate();对象销毁自己
3,Session对象的默认失效时间是30分钟,在tomcat服务器的web.xml文件中,可以更改失效时间。当然要是项目使用XML配置也可以使用web.xml对其配置
在web.xml中如图:

目录下的WEB.xml文件
失效时间配置

  • 3.Session会话技术的特点
    1.Session用于存储一次会话的多次请求的数据,存储在服务器端
    2.Session可以存储任意类型任意大小的数据
    相对安全,可以存放大量数据,不用考虑数据的类型
    例如:在重定向中,由于是多次请求,我们可以考虑采用Session个Application Context 存放数据,但是我们一般存放在Session对象中,因为Application Context对象的作用域太大了,Session在会话域中使用的十分广泛


cookie和session的区别:
1,session数据存档在服务器端,而cookie在客户端
2,session没有大小限制,但是cookie有
3,session的数据相对安全,cookie相对不安全

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容