多个Servlet之间调用规则

前提条件

  • 某些来自于浏览器发送的请求,往往需要服务端中多个Servlet协同处理。
  • 但是浏览器一次只能访问一个Servlet,导致用户需要多次发起请求,才能的到结果
  • 增加用户获取服务单独,导致用户放弃访问

    提高用户使用感受规则

  • 无论本次请求设计到多个Servlet,用户只需要通知一次浏览器发起一次请求即可

    多个Servlet之间调用规则

  • 重定向解决方案

  • 请求转发解决方案

重定向解决方案

工作原理

  1. 用户第一次通过手动的方式,通知浏览器访问 OneServlet,当OneServlet执行完毕后,将TwoServlet地址写道响应头中的 location属性中
  2. 导致tomcat将302的状态码,写入状态行中。
  3. 在浏览器接收到响应包之后,会读取到302状态。此时浏览器自动根据响应头的location属性地址发起第二次请求,访问TwoServlet去完成请求中的剩余任务

    实现命令

    response.sendRedirect(“请求地址”); // 将地址写入响应包中的响应头中location属性中

    地址格式:/myWeb/two /网站名/资源文件名

特征

请求地址

  • 既可以把当前网站内部的资源文件地址发给浏览器 (/网站名/资源名)
  • 又可以把其他网站资源文件地址发送给浏览器(http://ip:端口号/网站名/资源名)

    请求次数

  • 浏览器至少发送两次请求,只有第一次请求是用户手动发送的,后续的都是浏览器自动发送的

    请求方式

  • TwoServlet的请求方式是get

  • 重定向的解决方案中,通过地址栏通知浏览器发起下一次请求,所以是get
  • 通过重定向解决方案调用的资源文件接收的请求方式一定是get

    缺点

  • 重定向结局方案需要在浏览器与服务器之间进行多次的往返,大量的时间消耗在往返的次数,增加用户等待服务时间


请求转发解决方案

工作原理

  1. 用户第一次通过手动方式请求浏览器访问OneServlet. OneServlet工作完毕后,通过当前的请求对象代替浏览器向Tomcat发送请求,申请调用TwoServlet
  2. Tomcat在接收这个请求之后,自动调用TwoServlet来完成剩余任务

    实现命令

    RequestDispatcher report = request.getRequestDispatcher(“/资源文件名称”); // 通过当前请求对象生成资源文件申请报告对象
    一定要/ 开头
    report.forward(当前请求对象,当前的响应对象) //将报告对象发送给Tomcat

    优点

  • 无论本次请求涉及多少个servlet,用户只需要手动的发起一次请求
  • servlet之间的调用发生在服务端计算机中,节省了服务端和浏览器之间往返次数

    特征

  • 请求次数

    • 在请求转发过程中,浏览器只发送了一次请求
  • 请求地址
    • 只能向tomcat服务器申请调用当前网络下资源文件地址(不要写网站名)
    • request.getRequestDispathcer(“/资源文件名”)
  • 请求方式
    • 与浏览器所发送的请求方式一致

数据共享

概述

OneServlet执行完毕后,将产生的数据交给TwoServlet使用
四种数据共享方案

  1. ServletContext 接口
  2. Cookie类
  3. HttpSession 接口
  4. HttpServletRequest接口

ServletContext接口

介绍

  • 来自于Servlet规范中的一个接口。在tomcat中存在 servlet-api.jar
  • 在tomcat中负责提供这个接口实现类
  • 如果两个Servlet来自同一个网站,那么他们彼此之间就可以通过ServletContext实例对象实现数据共享
  • 开发人员习惯叫他为【全局作用域对象】

    工作原理

  • 每一个网站里面都存在一个全局作用域对象

  • 全局作用域对象 【相当于】 map集合【键值对】可看作为一个公共的留言板
  • 在这个网站中 ,OneServlet可以将一个数据存入到全局作用域对象,当前网站中其他的Servlet都可以从这个全局作用域对象中得到这个数据

    生命周期

  • 在Http服务器启动的过程中,自动为当前网站在内存中创建一个全局作用域对象

自动创建 就单独一个

  • 在http服务器运行下 全局作用域对象存活状态 | http服务器关闭,全局作用域销毁。

【贯穿当前网站整个运行期间】

命令实现

同一个网站 OneServlet将数据共享给TwoServlet

  1. public class OneServlet extends HttpServlet {
  2. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  3. //1.通过请求对象向Tomcat索要当前网站中的【全局作用域对象】
  4. ServletContext application = request.getServletContext();
  5. //2.将数据添加到全局作用域当中 作为共享数据
  6. application.setAttribute("key1","Hello World");
  7. }
  8. }

在TwoServlet里面访问 已经保存好的key1对应的值

  1. public class TwoServlet extends HttpServlet {
  2. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  3. //得到全局作用域对象
  4. ServletContext application = request.getServletContext();
  5. //得到指定关键字的指定数据 返回一个Object类型的数据
  6. Object s = application.getAttribute("key1");
  7. //强转
  8. String ss = (String) s;
  9. //输出到控制台
  10. System.out.println(ss);
  11. }
  12. }

全局作用域对象的变量名 建议叫 application application.removeAttribute(“key1”) // 通过key 删除对应key1的共享数据

Cookie

介绍

  • 来自Servlet规范的一个工具类。 存在tomcat提供的servlet-api.jar
  • 如果两个Servlet来自于同一个网站,并且为同一个浏览器/用户提供服务时,此时借助于Cookie对象进行数据共享
  • Cookie里面存放当前用户的私人数据,在共享数据过程中提高服务质量
  • Cookie 相当于会员卡

    原理

  • 用户通过浏览器第一次向myWeb 网站发送请求申明OneServlet

  • OneServlet在运行期间创建了一个Cookie存储当前用户相关数据
  • OneServlet工作完毕后,【将Cookie写入到响应头】交还给当前浏览器
  • 浏览器收到响应包之后,将Cookie存储到浏览器的缓存中
  • 一段时间之后,用户通过【同一个浏览器】再次向【myWeb网站】发送请求申请TwoServlet时。
  • 【浏览器需要无条件的将myWeb网站之前推送过来的Cookie,写入到请求头中】发送过去
  • 此时TwoServlet在运行时,就可以通过读取请求头中的Cookie中的信息,得到OneServlet提供的共享数据

实现命令

同一个网站中 OneServlet和TwoServlet借助Cookie来实现数据的共享方案
在OnewServlet中创建一个Cookie

  1. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  2. //1.创建Cookie对象,保存共享数据(当前用户数据)
  3. Cookie cookie = new Cookie("key","HelloWorld");
  4. //cookie 实际上也是一个map
  5. //一个cookie对象只能放一个键值对
  6. //这个键值对的key和value只能是String(key不能是中文)
  7. //2.把卡交给用户【把cookie写入到响应头中,交给浏览器】
  8. response.addCookie(cookie);
  9. }

TwoServlet中访问Cookie

  1. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  2. //调用请求对象,从请求头中得到浏览器返回的Cookie
  3. //将请求头中的所有cookie封装成一个数组进行返回
  4. Cookie[] cookies = request.getCookies();
  5. //循环遍历数组,得到每一个key和value
  6. for (Cookie c : cookies){
  7. String key = c.getName(); // 读取的是key
  8. String value = c.getValue(); // 读取的是value
  9. System.out.println(key);
  10. System.out.println(value);
  11. }
  12. }

Cookie生命周期

Cookie销毁时机

  • 默认的情况下,Cookie存放在浏览器的缓存中
  • 只要浏览器关闭,缓存清除,Cookie被销毁
  • 在手动设置情况下,可以要求浏览器将接收的Cookie存放在客户端计算机上的硬盘上同时需要去指定Cookie在硬盘上的存活时间。在存活时间范围内,关闭服务器,关闭浏览器,都不会导致Cookie销毁。 存活时间到达Cookie被自动销毁

cookie.setMaxAge(60); //表示当前的cookie对象 在硬盘上存活1分钟【秒】

HttpSession接口

介绍

  • 来自于Servlet规范下一个接口,存在于Tomcat中servlet-api.jar
  • 其实现类又http服务器提供
  • 如果两个Servlet来自于同一个网站,并且为同一个浏览器/用户提供服务时,此时借助于HttpSession对象进行数据共享
  • 开发人员称被HttpSession接口修饰的对象为 【会话作用域对象】

    HttpSession和Cookie的区别

  • 存储位置不同

    • Cookie:存放在客户端的计算机中【浏览器缓存或者硬盘】
    • HttpSession:存放在服务端计算机内存中
  • 数据类型不同:
    • Cookie:存储的共享数据只能是String
    • HttpSession对象可以存储任意类型的共享数据
  • 数据的数量
    • 一个Cookie 只能存储一个共享数据
    • HttpSession 使用map集合共享数据,可以存储任意数量的数据
  • 参照物不同
    • Cookie相当于服务端的会员卡
    • HttpSession 相当于客户在服务端的私人保险柜【大,多】

命令实现

同一个网站下,OneServlet将数据传递给TwoServlet
OneServlet中写入共享数据

  1. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  2. //1.调用请求对象向Tomcat索要当前用户在服务端的私人储物柜
  3. //返回一个HttpSession对象 程序员们习惯叫他为session
  4. HttpSession session = request.getSession();
  5. //2. 将数据 添加到用户私人储物柜中
  6. session.setAttribute("key1","Hello World");
  7. }

TwoServlet 中读取共享数据

  1. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  2. // 访问共享数据
  3. //1.通过请求对象向Tomcat索要用户的私人储物柜
  4. HttpSession session = request.getSession();
  5. //2.从会话作用域对象中,得到OneServlet提供的共享数据(通过key得到value)
  6. //返回一个Object类型的数据
  7. String value = (String)session.getAttribute("key1");
  8. System.out.println(value);
  9. }

Http服务器如何将用户和HttpSession关联起来的呢

  • 当用户点击了加入购物车后,服务端执行到OneServlet里面的代码了
  • 会看有没有Session 如果没有就会新建一个,并且创建一个Cookie并且返回给浏览器【JSESSIONID = 12452..】
  • 当用户第二次访问的时候 ,请求头里面有一个Cookie 服务端接收到之后,有了ID就开对了箱子 【类似于浴池的手牌】

    getSession(); 和getSession(false); 的区别【有参无参】

    首先都是索要全局对话作用域对象

    getSession();

  • //如果当前用户在服务端中,已经拥有了私人储物柜

  • 那么则要求tomcat返回这个私人储物柜
  • 如果当前用户尚未拥有自己的私人储物柜,那么Tomcat就会创建一个全新的私人储物柜
  • 在哪些地方出现: 登陆验证(就这一个地方)【用户身份合法 创建一个Session】


    **getSession(false)**

  • //如果当前用户在服务端中,已经拥有了私人储物柜

  • 那么则要求tomcat返回这个私人储物柜
  • 如果当前用户端在服务端中没有自己的私人储物柜,
  • 那么tomcat就会返回一个null
  • 在哪里出现: 其余的资源文件中 都用有参 因为不知道是不是恶意登录

    什么时候用有参/无参

  • 当前用户事合法登录的【通过登陆验证】 用无参

  • 当前用户身份尚未确认【翻墙】 用有参

    生命周期

  • 用户和HttpSesion关联使用的Cookie只能存放在浏览器的缓存中

  • 在浏览器关闭的时候 意味着用户与HttpSession的关系被切断
  • 由于Tomcat无法去监测浏览器何时关闭,因此在浏览器关闭时并不会导致Tomcat将浏览器中的Cookie和HttpSession进行销毁
  • 为了解决问题,tomcat会为每一个HttpSession对象设置一个空闲时间【开始——现在】 默认30分钟, 当前Session对象达到30分钟,Tomcat认为用户放弃了自己的Session 此时就会销毁

    HttpSession空闲时间的手动设置

    当前网站下 / web / WEB-INF/web.xml
    1. <session-config>
    2. <!-- 表示当前网站中对大的空闲时间为5分钟,5分后自动销毁-->
    3. <session-timeout>5<session-timeout>
    4. </session-config>

HttpServletRequest接口实现数据共享

介绍

  • 如果在同一个网站中两个Servlet之间通过请求转发的方式来进行调用,此时彼此之间将共享同一个请求协议包。而一个请求协议包只对应一个请求对象/响应对象因此servlet之间共享同一个请求对象,此时就可以利用请求对象在两个Servelt之间实现数据共享
  • 请求对象可以存放数据【有存放数据的属性 Attribute属性】,响应对象不可以存放数据,所以就可以用请求对象来实现共享
  • 在请求对象实现Servlet之间数据共享的功能的时候,开发人员将请求对象叫【请求作用域对象】


实现命令

OneServlet通过请求转发申请调用TwoServelt的时候,需要给TwoServlet提供共享数据
在OneServlet中写入共享数据

  1. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  2. // 1.将数据添加到【请求作用域对象】中的Attribute属性
  3. // value的类型可以是任何类型【map集合 key value】
  4. request.setAttribute("key1","HelloWorld");
  5. //2.向Tomcat申请调用TwoServlet,并别发给tomcat【请求对象,响应对象】
  6. request.getRequestDispatcher("/two").forward(request,response);
  7. }

在TwoSerlet中读取共享数据

  1. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  2. //1.因为是请求转发,所以TwoServlet使用的请求对象/响应对象和OneServlet使用的是一个
  3. //从当前请求对象中得到OneServlet所写入的共享数据
  4. String s = (String) request.getAttribute("key1");
  5. System.out.println(s);
  6. }