请求域对象
一、应用域对象
[x] 应用域对象是什么?
- ServletContext(Servlet上下文对象)
什么时候会考虑向ServletCOntext这个应用域当中绑定数据?
- 所有用户共享的数据
- 这个共享数据量很小
- 这个共享数据量很少的修改操作
- 以上三个条件都满足的情况下,使用这个应用域对象,可以大大提高我们程序执行效率
- 实际上向应用域中绑定数据,就相当于把数据放到了缓存中,然后用户访问的时候,直接从缓存中区域,减少IO的操作,大提高系统的性能,所以缓存技术系统是提高系统性能的重要手段
缓存技术
- 字符串常量池
- 整数常量池[-128-127]
- 数据库连接池(提前创建好N个连接对象,将连接对象放到集合中,使用连接对象的时候,直接从缓存中拿,省去了连接对象的创建过程。效率提升
- 线程池(Tomcat服务器就是支持多线程的,所谓的线程池就是提前创建好N个线程对象,将线程对象存储到集合中,然后用户请求过来之后,直接从线程池中获取线程对象,直接拿来用,提升系统性能
- …………
- ServletContext中的三个操作域方法
void setAttribute(String name,Object obj);//向域中绑定数据
Object getAttribute(String name);//从域中根据name获取数据
void removeAttribute(String name);//将域中绑定的数据移除
//以上操作类类似于Map方法
Map<String,Object>map;
map.out("name",obj);//向map集合中放key和Value
Object obj = map.get("name");//通过Map集合的key删除key和value这个键值对
二、请求域对象
- request对象实际上又称为“请求域对象”
- 请求域对象要比应用域对象范围小很多,生命周期短很多,请求域只在一次请求内有效
- 一个请求对象request对应一个请求域对象。一次请求域结束以后,这个请求域就销毁了
- 请求域对象也有跟应用域一样的三个方法
void setAttribute(String name,Object obj);//向域中绑定数据
Object getAttribute(String name);//从域中根据name获取数据
void removeAttribute(String name);//将域中绑定的数据移除
三、请求域和应用域的选用原则
- 尽量使用小的域对象,因为小的域对象占用资源较少
四、实现
4.1 实现请求
package request;
/**
* @Author: 小雷学长
* @Date: 2022/3/21 - 11:40
* @Version: 1.8
*/
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;
public class AServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获取系统时间
Date nowTime = new Date();
//向request域中绑定数据
request.setAttribute("nowTime", nowTime);
//从request域中取出绑定的数据
Object obj = request.getAttribute("nowTime");
//输出到浏览器
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.print("request域当中获取的系统当前时间 = " + obj);
}
}
4.2 出现问题
- 若在AServlet绑定数据,用BServlet获取,是无法获取的,因为是两次请求了
package request;
/**
* @Author: 小雷学长
* @Date: 2022/3/21 - 11:40
* @Version: 1.8
*/
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;
public class AServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获取系统时间
Date nowTime = new Date();
//向request域中绑定数据
request.setAttribute("nowTime", nowTime);
}
}
package request;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* @Author: 小雷学长
* @Date: 2022/3/21 - 11:40
* @Version: 1.8
*/
public class BServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//从request域中取出绑定的数据
Object obj = request.getAttribute("nowTime");
//输出到浏览器
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.print("request域当中获取的系统当前时间 = " + obj);
}
}
4.3 解决 使用Servlet中请求转发机制
- 问题:请求域只能请求一次,无法实现AServlet转跳到BServlet
- 解决:让AServlet和BServlet放到一次请求中,使用Servlet当中的请求转发机制
(1)跳转,转发机制
- 转发
- 获取请求转发对象
RequestDispatcher dispatcher = request.getRequestDispatcher("/bservlet");
- 调用转发器的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对象中两个容易混淆的方法
第一个方法:String value = request.getPatameter("name");
第二个方法:Object obj = request.getAttribute("name");
[x] 以上两个方法的区别是
- 第一个方法:获取的是用户在浏览器上提交的数据
- 第二个方法:获取的是请求栏中绑定的数据
4.4 实现一个HTML转发机制
package request;
/**
* @Author: 小雷学长
* @Date: 2022/3/21 - 11:40
* @Version: 1.8
*/
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;
public class AServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获取系统时间
Date nowTime = new Date();
//向request域中绑定数据
request.setAttribute("nowTime", nowTime);
//第一步:获取请求转发器对象
RequestDispatcher dispatcher = request.getRequestDispatcher("/test.html");
//第二步:调用请求转发器RequestDispatcher的forward方法进行转发
dispatcher.forward(request,response);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Test HTML</h1>
</body>
</html>