前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >14. Servlet入门 - ServletContext类作为全局域对象共享数据使用

14. Servlet入门 - ServletContext类作为全局域对象共享数据使用

作者头像
Devops海洋的渔夫
发布2022-01-14 17:45:50
5260
发布2022-01-14 17:45:50
举报
文章被收录于专栏:Devops专栏

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.mp3b.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);

    }

}

小结

  1. 作为域对象存取数据【共享】
    • setAttribute(String name,Object value) 存
    • getAttribute(String name) 取
    • removeAttribute(String name) 移除
  2. 获得文件的Mime类型
    • getMineType(String fileName);
  3. 获得全局初始化参数
    • 在web.xml配置
    • getInitParameter(String name);
  4. 获得web资源路径【已经在web目录了】
    • getRealPath(String file); 获得文件的绝对路径
    • getReSourceAsStream(String file); 获得文件流
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-11-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 海洋的渔夫 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 14. Servlet入门 - ServletContext类作为全局域对象共享数据使用
    • ServletContext 类
      • 什么是 ServletContext?
      • ServletContext 类的作用
      • 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档