1、应用域对象
- 应用域对象是什么?
- ServletContext(Servlet上下文对象)
- 什么时候会考虑向ServletCOntext这个应用域当中绑定数据?
- 所有用户共享的数据
- 这个共享数据量很小
- 这个共享数据量很少的修改操作
- 以上三个条件都满足的情况下,使用这个应用域对象,可以大大提高我们程序执行效率
- 实际上向应用域中绑定数据,就相当于把数据放到了缓存中,然后用户访问的时候,直接从缓存中区域,减少IO的操作,大提高系统的性能,所以缓存技术系统是提高系统性能的重要手段
- 缓存技术
- 字符串常量池
- 整数常量池[-128-127]
- 数据库连接池(提前创建好N个连接对象,将连接对象放到集合中,使用连接对象的时候,直接从缓存中拿,省去了连接对象的创建过程。效率提升
- 线程池(Tomcat服务器就是支持多线程的,所谓的线程池就是提前创建好N个线程对象,将线程对象存储到集合中,然后用户请求过来之后,直接从线程池中获取线程对象,直接拿来用,提升系统性能
- …………
- ServletContext中的三个操作域方法 ```java void setAttribute(String name,Object obj);//向域中绑定数据 Object getAttribute(String name);//从域中根据name获取数据 void removeAttribute(String name);//将域中绑定的数据移除
//以上操作类类似于Map方法
Map
<a name="WiMpT"></a>
# 2、请求域对象
- [x] request对象实际上又称为“请求域对象”
- [x] 请求域对象要比应用域对象范围小很多,生命周期短很多,请求域只在一次请求内有效
- [x] 一个请求对象request对应一个请求域对象。一次请求域结束以后,这个请求域就销毁了
- [x] 请求域对象也有跟应用域一样的三个方法
```java
void setAttribute(String name,Object obj);//向域中绑定数据
Object getAttribute(String name);//从域中根据name获取数据
void removeAttribute(String name);//将域中绑定的数据移除
3、请求域和应用域的选用原则
/**
- @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);
}
}
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2560440/1647836892223-5d324f0b-5e2f-4c9e-83a3-54676b4c4422.png#clientId=ua440ae4a-86c0-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=421&id=u7b3eba6f&margin=%5Bobject%20Object%5D&name=image.png&originHeight=631&originWidth=1232&originalType=binary&ratio=1&rotation=0&showTitle=false&size=47341&status=done&style=none&taskId=u8fff0b8f-66d2-41f5-8bbb-273c3ece2e9&title=&width=821.3333333333334)
<a name="b52z7"></a>
## 4.2 出现问题
- [x] 若在AServlet绑定数据,用BServlet获取,是无法获取的,因为是两次请求了
```java
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
[x] 解决:让AServlet和BServlet放到一次请求中,使用Servlet当中的请求转发机制
4.3.1 跳转,转发机制
[x] 转发
- 获取请求转发对象
RequestDispatcher dispatcher = request.getRequestDispatcher("/bservlet");
- 调用转发器的forward方法完成跳转/转发
dispatcher.forward(request,response);
[x] 第1步和第2步代码可以合二为一:
request.getRequestDispatcher("/bservlet".forward(request,response);
4.3.2 两个Servlet共享数据
[x] 将数据放到ServletContext应用中,当然是可以的,但是应用域范围太大,占用资源太多,不建议使用
- 可以将数据存放到request域当中,然后AServlet转发到BServlet,保证AServlet在同一次请求当中,这样就可以做到两个Servlet,或者多个Servlet共享一份数据
- 转发的资源不一定是Servlet,只要是Tomcat服务器合法的资源都可以
-
4.3.3 request对象中两个容易混淆的方法
第一个方法:String value = request.getPatameter("name");
第二个方法:Object obj = request.getAttribute("name");
[x] 以上两个方法的区别是
/**
- @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);
```java
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Test HTML</h1>
</body>
</html>