请求域对象

一、应用域对象

  • [x] 应用域对象是什么?

    • ServletContext(Servlet上下文对象)
    • 什么时候会考虑向ServletCOntext这个应用域当中绑定数据?

      • 所有用户共享的数据
      • 这个共享数据量很小
      • 这个共享数据量很少的修改操作
      • 以上三个条件都满足的情况下,使用这个应用域对象,可以大大提高我们程序执行效率
      • 实际上向应用域中绑定数据,就相当于把数据放到了缓存中,然后用户访问的时候,直接从缓存中区域,减少IO的操作,大提高系统的性能,所以缓存技术系统是提高系统性能的重要手段
    • 缓存技术

      • 字符串常量池
      • 整数常量池[-128-127]
      • 数据库连接池(提前创建好N个连接对象,将连接对象放到集合中,使用连接对象的时候,直接从缓存中拿,省去了连接对象的创建过程。效率提升
      • 线程池(Tomcat服务器就是支持多线程的,所谓的线程池就是提前创建好N个线程对象,将线程对象存储到集合中,然后用户请求过来之后,直接从线程池中获取线程对象,直接拿来用,提升系统性能
      • …………
    • ServletContext中的三个操作域方法
  1. void setAttribute(String name,Object obj);//向域中绑定数据
  2. Object getAttribute(String name);//从域中根据name获取数据
  3. void removeAttribute(String name);//将域中绑定的数据移除
  4. //以上操作类类似于Map方法
  5. Map<String,Object>map;
  6. map.out("name",obj);//向map集合中放key和Value
  7. Object obj = map.get("name");//通过Map集合的key删除key和value这个键值对

二、请求域对象

  • request对象实际上又称为“请求域对象”
  • 请求域对象要比应用域对象范围小很多,生命周期短很多,请求域只在一次请求内有效
  • 一个请求对象request对应一个请求域对象。一次请求域结束以后,这个请求域就销毁了
  • 请求域对象也有跟应用域一样的三个方法
  1. void setAttribute(String name,Object obj);//向域中绑定数据
  2. Object getAttribute(String name);//从域中根据name获取数据
  3. void removeAttribute(String name);//将域中绑定的数据移除

三、请求域和应用域的选用原则

  • 尽量使用小的域对象,因为小的域对象占用资源较少

四、实现

4.1 实现请求

  1. package request;
  2. /**
  3. * @Author: 小雷学长
  4. * @Date: 2022/3/21 - 11:40
  5. * @Version: 1.8
  6. */
  7. import jakarta.servlet.ServletException;
  8. import jakarta.servlet.http.HttpServlet;
  9. import jakarta.servlet.http.HttpServletRequest;
  10. import jakarta.servlet.http.HttpServletResponse;
  11. import java.io.IOException;
  12. import java.io.PrintWriter;
  13. import java.util.*;
  14. public class AServlet extends HttpServlet {
  15. @Override
  16. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  17. throws ServletException, IOException {
  18. //获取系统时间
  19. Date nowTime = new Date();
  20. //向request域中绑定数据
  21. request.setAttribute("nowTime", nowTime);
  22. //从request域中取出绑定的数据
  23. Object obj = request.getAttribute("nowTime");
  24. //输出到浏览器
  25. response.setContentType("text/html");
  26. PrintWriter out = response.getWriter();
  27. out.print("request域当中获取的系统当前时间 = " + obj);
  28. }
  29. }

3、请求域对象 - 图1

4.2 出现问题

  • 若在AServlet绑定数据,用BServlet获取,是无法获取的,因为是两次请求了
  1. package request;
  2. /**
  3. * @Author: 小雷学长
  4. * @Date: 2022/3/21 - 11:40
  5. * @Version: 1.8
  6. */
  7. import jakarta.servlet.ServletException;
  8. import jakarta.servlet.http.HttpServlet;
  9. import jakarta.servlet.http.HttpServletRequest;
  10. import jakarta.servlet.http.HttpServletResponse;
  11. import java.io.IOException;
  12. import java.io.PrintWriter;
  13. import java.util.*;
  14. public class AServlet extends HttpServlet {
  15. @Override
  16. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  17. throws ServletException, IOException {
  18. //获取系统时间
  19. Date nowTime = new Date();
  20. //向request域中绑定数据
  21. request.setAttribute("nowTime", nowTime);
  22. }
  23. }
  1. package request;
  2. import jakarta.servlet.ServletException;
  3. import jakarta.servlet.http.HttpServlet;
  4. import jakarta.servlet.http.HttpServletRequest;
  5. import jakarta.servlet.http.HttpServletResponse;
  6. import java.io.IOException;
  7. import java.io.PrintWriter;
  8. import java.util.Enumeration;
  9. import java.util.Iterator;
  10. import java.util.Map;
  11. import java.util.Set;
  12. /**
  13. * @Author: 小雷学长
  14. * @Date: 2022/3/21 - 11:40
  15. * @Version: 1.8
  16. */
  17. public class BServlet extends HttpServlet {
  18. @Override
  19. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  20. throws ServletException, IOException {
  21. //从request域中取出绑定的数据
  22. Object obj = request.getAttribute("nowTime");
  23. //输出到浏览器
  24. response.setContentType("text/html");
  25. PrintWriter out = response.getWriter();
  26. out.print("request域当中获取的系统当前时间 = " + obj);
  27. }
  28. }

3、请求域对象 - 图2

4.3 解决 使用Servlet中请求转发机制

  • 问题:请求域只能请求一次,无法实现AServlet转跳到BServlet
  • 解决:让AServlet和BServlet放到一次请求中,使用Servlet当中的请求转发机制

(1)跳转,转发机制

  • 转发
  1. 获取请求转发对象RequestDispatcher dispatcher = request.getRequestDispatcher("/bservlet");
  2. 调用转发器的forward方法完成跳转/转发dispatcher.forward(request,response);
  • 第1步和第2步代码可以合二为一:request.getRequestDispatcher("/bservlet".forward(request,response);

(2)两个Servlet共享数据

  • 将数据放到ServletContext应用中,当然是可以的,但是应用域范围太大,占用资源太多,不建议使用
  • 可以将数据存放到request域当中,然后AServlet转发到BServlet,保证AServlet在同一次请求当中,这样就可以做到两个Servlet,或者多个Servlet共享一份数据
  • 转发的资源不一定是Servlet,只要是Tomcat服务器合法的资源都可以
  • 转发路径以"/"开始,不加项目名

(3)request对象中两个容易混淆的方法

  1. 第一个方法:String value = request.getPatameter("name");
  2. 第二个方法:Object obj = request.getAttribute("name");
  • [x] 以上两个方法的区别是

    • 第一个方法:获取的是用户在浏览器上提交的数据
    • 第二个方法:获取的是请求栏中绑定的数据

4.4 实现一个HTML转发机制

  1. package request;
  2. /**
  3. * @Author: 小雷学长
  4. * @Date: 2022/3/21 - 11:40
  5. * @Version: 1.8
  6. */
  7. import jakarta.servlet.RequestDispatcher;
  8. import jakarta.servlet.ServletException;
  9. import jakarta.servlet.http.HttpServlet;
  10. import jakarta.servlet.http.HttpServletRequest;
  11. import jakarta.servlet.http.HttpServletResponse;
  12. import java.io.IOException;
  13. import java.io.PrintWriter;
  14. import java.util.*;
  15. public class AServlet extends HttpServlet {
  16. @Override
  17. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  18. throws ServletException, IOException {
  19. //获取系统时间
  20. Date nowTime = new Date();
  21. //向request域中绑定数据
  22. request.setAttribute("nowTime", nowTime);
  23. //第一步:获取请求转发器对象
  24. RequestDispatcher dispatcher = request.getRequestDispatcher("/test.html");
  25. //第二步:调用请求转发器RequestDispatcher的forward方法进行转发
  26. dispatcher.forward(request,response);
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <h1>Test HTML</h1>
  9. </body>
  10. </html>

3、请求域对象 - 图3