14. Servlet入门 - ServletContext类作为全局域对象共享数据使用
ServletContext 类
image-20201112001610037
什么是 ServletContext?
2、一个 web 工程,只有一个 ServletContext 对象实例。
3、ServletContext 对象是一个域对象。
4、ServletContext 是在 web 工程部署启动的时候创建。在 web 工程停止的时候销毁。
什么是域对象?
域对象,是可以像 Map 一样存取数据的对象,叫域对象。
这里的域指的是存取数据的操作范围,整个 web 工程。
代码语言:javascript复制 存数据 取数据 删除数据
Map put() get() remove()
域对象 setAttribute() getAttribute() removeAttribute();
ServletContext 类的作用
1、获取 web.xml 中配置的上下文参数 context-param
2、获取当前的工程路径,格式: /工程路径
3、获取工程部署后在服务器硬盘上的绝对路径
4、像 Map 一样存取数据
5、获得文件mini类型(文件下载)
6、获取web资源路径 ,可以将Web资源转换成字节输入流(掌握)
获取 web.xml 上下文、工程路径、部署路径
1.首先创建一个新的Servlet用来测试
image-20201112081828738
代码语言:javascript复制import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author Aron.li
* @date 2020/11/12 8:18
*/
public class ContextServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
2.配置该Servlet 的 XML 以及 上下文参数 context-param
image-20201112082219781
代码语言:javascript复制<!--context-param 是上下文参数(它属于整个 web 工程)-->
<context-param>
<param-name>username</param-name>
<param-value>root</param-value>
</context-param>
<!--context-param 是上下文参数(它属于整个 web 工程)-->
<context-param>
<param-name>password</param-name>
<param-value>123abc</param-value>
</context-param>
<!-- ContextServlet -->
<servlet>
<servlet-name>ContextServlet</servlet-name>
<servlet-class>com.test01.ContextServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ContextServlet</servlet-name>
<url-pattern>/context</url-pattern>
</servlet-mapping>
3.获取 web.xml 中配置的上下文参数 context-param
image-20201112082706231
代码语言:javascript复制protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("ContextServlet的Get方法:");
//1. 获取 web.xml 中配置的上下文参数 context-param
ServletContext context = getServletContext(); // 获取ServletContext对象
// 获取上下文username参数
String username = context.getInitParameter("username");
System.out.println("context-param参数username的值是:" username);
// 获取上下文password参数
String password = context.getInitParameter("password");
System.out.println("context-param参数password的值是:" password);
}
4.获取当前的工程路径,格式: /工程路径
image-20201112083059383
代码语言:javascript复制// 获取ServletContext对象
ServletContext context = getServletContext();
//2.获取当前的工程路径,格式: /工程路径
System.out.println("当前工程路径:" context.getContextPath());
5. 获取工程部署后在服务器硬盘上的绝对路径
5.1 获取工程的根路径部署地址
image-20201112084010482
代码语言:javascript复制//3. 获取工程部署后在服务器硬盘上的绝对路径
/**
* / 斜杠被服务器解析地址为:http://ip:port/工程名/ 映射到IDEA代码的web目录<br/>
*/
System.out.println("工程部署的路径是:" context.getRealPath("/"));
我们可以看到打印硬盘部署路径,可以打开该路径看看,如下:
image-20201112084103281
5.2 除了获取工程的根路径,还可以任意拼接其他路径,就算该路径在硬盘中并不存在
image-20201112084432449
代码语言:javascript复制// 除了获取工程的根路径,还可以任意拼接其他路径,就算该路径在硬盘中并不存在
System.out.println("工程下css目录的绝对路径是:" context.getRealPath("/css"));
System.out.println("工程下imgs目录1.jpg的绝对路径是:" context.getRealPath("/imgs/1.jpg"));
6.演示代码
ServletContext 演示代码:
代码语言:javascript复制package com.test01;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author Aron.li
* @date 2020/11/12 8:18
*/
public class ContextServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("ContextServlet的Get方法:");
//1. 获取 web.xml 中配置的上下文参数 context-param
ServletContext context = getServletContext(); // 获取ServletContext对象
// 获取上下文username参数
String username = context.getInitParameter("username");
System.out.println("context-param参数username的值是:" username);
// 获取上下文password参数
String password = context.getInitParameter("password");
System.out.println("context-param参数password的值是:" password);
//2.获取当前的工程路径,格式: /工程路径
System.out.println("当前工程路径:" context.getContextPath());
//3. 获取工程部署后在服务器硬盘上的绝对路径
/**
* / 斜杠被服务器解析地址为:http://ip:port/工程名/ 映射到IDEA代码的web目录<br/>
*/
System.out.println("工程部署的路径是:" context.getRealPath("/"));
// 除了获取工程的根路径,还可以任意拼接其他路径,就算该路径在硬盘中并不存在
System.out.println("工程下css目录的绝对路径是:" context.getRealPath("/css"));
System.out.println("工程下imgs目录1.jpg的绝对路径是:" context.getRealPath("/imgs/1.jpg"));
}
}
web.xml 中的配置
代码语言:javascript复制<!--context-param 是上下文参数(它属于整个 web 工程)-->
<context-param>
<param-name>username</param-name>
<param-value>root</param-value>
</context-param>
<!--context-param 是上下文参数(它属于整个 web 工程)-->
<context-param>
<param-name>password</param-name>
<param-value>123abc</param-value>
</context-param>
<!-- ContextServlet -->
<servlet>
<servlet-name>ContextServlet</servlet-name>
<servlet-class>com.test01.ContextServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ContextServlet</servlet-name>
<url-pattern>/context</url-pattern>
</servlet-mapping>
ServletContext 像 Map 一样存取数据
1.创建一个 ContextServlet1 来进行演示
image-20201112234407498
代码语言:javascript复制public class ContextServlet1 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
配置 web.xml 如下:
image-20201112234436149
代码语言:javascript复制<!-- ContextServlet1 -->
<servlet>
<servlet-name>ContextServlet1</servlet-name>
<servlet-class>com.test01.ContextServlet1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ContextServlet1</servlet-name>
<url-pattern>/context1</url-pattern>
</servlet-mapping>
2.在 ContextServlet1 存储数据 以及 读取数据
image-20201112234728361
代码语言:javascript复制protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取ServletContext对象
ServletContext context = getServletContext();
//在 ContextServlet1 存储数据 以及 读取数据
context.setAttribute("key1", "value1"); // 存储数据
System.out.println("ContextServlet1 读取数据: " context.getAttribute("key1")); // 读取数据
}
3.启动 tomcat 服务,请求测试如下:
image-20201112235130305
可以看到能够读取数据。另外,context 存储的数据是共享于整个 web 工程的,也就是说其他的 Servlet 程序也是可以读取的。
4.再创建一个 ContextServlet2 ,尝试读取 ContextServlet1 存储的值
image-20201112235422146
代码语言:javascript复制public class ContextServlet2 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取ServletContext对象
ServletContext context = getServletContext();
//在 ContextServlet2 读取数据
System.out.println("ContextServlet2 读取数据: " context.getAttribute("key1")); // 读取数据
System.out.println("ContextServlet2 读取数据: " context.getAttribute("key1")); // 读取数据
System.out.println("ContextServlet2 读取数据: " context.getAttribute("key1")); // 读取数据
}
}
在 web.xml 配置如下:
image-20201112235448775
代码语言:javascript复制<!-- ContextServlet2 -->
<servlet>
<servlet-name>ContextServlet2</servlet-name>
<servlet-class>com.test01.ContextServlet2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ContextServlet2</servlet-name>
<url-pattern>/context2</url-pattern>
</servlet-mapping>
5.重新部署 tomcat 服务,尝试首先请求 ContextServlet2 能否读取到值
image-20201112235608372
也就是说,如果想要读取数据,首先需要设置数据。
6.访问 ContextServlet1 设置数据,然后再 ContextServlet2 读取数据
image-20201112235713767
image-20201112235749863
获得文件mime类型(文件下载)
对于这个用法了解一下就好,下面我们快速用代码示例一下。
获取文件mime类型的方法:
代码语言:javascript复制getServletContext().getMimeType(String file)
1.读取 a.mp3
和 b.png
的 文件mime类型
image-20201225000808315
不需要实际文件,根据字符串的后缀,可以直接识别对应的类型。测试如下:
image-20201225000930357
代码语言:javascript复制@WebServlet("/demo4")
public class ServletDemo4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//根据文件名获得文件的mini类型
//1.获得ServletContext
//2.调用getMimeType()方法
String file01 = "a.mp3";
String file02 = "b.png";
String mimeType01 = getServletContext().getMimeType(file01);
String mimeType02 = getServletContext().getMimeType(file02);
resp.getWriter().print("ServletDemo4... file01 mimetype: " mimeType01 ", file02 mimetype: " mimeType02 );
}
}
获取web资源路径 ,可以将Web资源转换成字节输入流(掌握)
我们在项目工程中获取文件的资源一般操作如下:
API
- String getRealPath(String path);根据资源名称得到资源的绝对路径.
- getResourceAsStream(String path) ;返回制定路径文件的流
“注意: filepath:直接从项目的根目录开始写 ”
在web项目中,将文件转换成流,有两种方式
如果文件在resources里面,使用类加载器
代码语言:javascript复制InputStream is = ServletDemo04.class.getClassLoader().getResourceAsStream("文件路径");
如果文件在web里面,使用ServletContext获取文件的路径后,再将其转为文件输入流。
代码语言:javascript复制InputStream resourceAsStream = servletContext.getResourceAsStream("1.jpeg");
1.拷贝一张图片在 webapp 目录下,并使用 ServletContext 获取编译后的存储路径
image-20201225083417208
代码语言:javascript复制@WebServlet("/demo5")
public class ServletDemo5 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 获取 图片 编译后的 存储路径
ServletContext servletContext = getServletContext();
String realPath = servletContext.getRealPath("1.jpeg");
System.out.println(realPath);
}
}
2.使用文件输入流读取文件内容
image-20201225083629036
代码语言:javascript复制@WebServlet("/demo5")
public class ServletDemo5 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 获取 图片 编译后的 存储路径
ServletContext servletContext = getServletContext();
String realPath = servletContext.getRealPath("1.jpeg");
System.out.println(realPath);
// 2. 使用文件输入流读取文件内容
FileInputStream fileInputStream = new FileInputStream(realPath);
System.out.println(fileInputStream);
}
}
可以看到,通过这种方式已经成功获取到了 webapp 目录下的图片资源了。但是还可以直接通过 ServletContext 对象获取文件资源。
3.使用ServletContext可以获取web里面的资源的真实路径
image-20201225084129069
代码语言:javascript复制@WebServlet("/demo5")
public class ServletDemo5 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 获取 图片 编译后的 存储路径
ServletContext servletContext = getServletContext();
String realPath = servletContext.getRealPath("1.jpeg");
System.out.println(realPath);
// 2. 使用文件输入流读取文件内容
FileInputStream fileInputStream = new FileInputStream(realPath);
System.out.println("fileInputStream: " fileInputStream);
// 3. 使用ServletContext可以获取web里面的资源的真实路径
InputStream resourceAsStream = servletContext.getResourceAsStream("1.jpeg");
System.out.println("resourceAsStream: " resourceAsStream);
}
}
小结
- 作为域对象存取数据【共享】
- setAttribute(String name,Object value) 存
- getAttribute(String name) 取
- removeAttribute(String name) 移除
- 获得文件的Mime类型
- getMineType(String fileName);
- 获得全局初始化参数
- 在web.xml配置
- getInitParameter(String name);
- 获得web资源路径【已经在web目录了】
- getRealPath(String file); 获得文件的绝对路径
- getReSourceAsStream(String file); 获得文件流