从 01 开始 从 01 开始
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机相关技巧
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • 最全面的 RSS 教程
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金
  • 职场规划
  • 关于离职
  • 杂谈
  • 自媒体
  • 📖 读书

    • 读书工具
    • 走进科学
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 新闻合订本
    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
    • 读书笔记
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档

晓林

程序猿,自由职业者,博主,英语爱好者,健身达人
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机相关技巧
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • 最全面的 RSS 教程
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金
  • 职场规划
  • 关于离职
  • 杂谈
  • 自媒体
  • 📖 读书

    • 读书工具
    • 走进科学
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 新闻合订本
    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
    • 读书笔记
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档
  • JavaSE

  • JavaSenior

  • JavaEE

  • JavaWeb

    • 服务器软件

    • 环境管理和配置管理-科普篇
    • Servlet 入门

      • 什么是 Servlet
      • Servlet 入门案例
      • Servlet 生命周期
      • Servlet 中的注解
      • Tomcat 集成 IDEA
      • Servlet 体系结构
      • HTTP 协议基础
      • 深入 request 和 response 对象
      • request 对象基本使用
      • request 其他功能
      • Servlet 实现登录功能
      • HTTP 协议基础-响应
      • Response 对象基本使用
      • response 对象之重定向
      • response 输出字符到浏览器
      • response 输出字节数据
      • 验证码案例
      • ServletContext
        • 获取和使用 ServletContext
        • ServletContext 的功能
        • 获取 MIME 类型
        • 域对象:共享数据
        • 获取文件的真实(服务器)路径
      • 文件下载案例
      • Cookie 笔记
      • Cookie 的更多细节
      • Cookie 实践:记住上次访问时间
      • JSP 入门
      • JSP 的内置对象和案例
      • IDEA 与 JavaWeb 的小技巧
      • Session 笔记
      • 验证码案例
      • JSP 深入学习
      • MVC 开发模式
      • EL 表达式和 JSTL 标签
      • JSTL 标签库
      • 案例:列表的增删改查
      • Filter 学习
      • Filter 案例
      • Listener 学习
      • Java 中的 Ajax
      • Java 中的 JSON
  • Spring

  • 主流框架

  • SpringMVC

  • SpringBoot

  • Java
  • JavaWeb
  • Servlet 入门
2023-04-17
目录

ServletContext

# 70.ServletContext

ServletContext 代表整个 web 应用,可以和程序的容器(服务器)来通信

# 获取和使用 ServletContext

‍ API 文档是这样描述 ServletContext 的:Defines a set of methods that a servlet uses to communicate with its servlet container, for example, to get the MIME type of a file, dispatch requests, or write to a log file.

获取 ServletContext 的方法:

  1. 通过 request 对象获取:request.getServletContext();
  2. 通过 HttpServlet 获取:this.getServletContext();

通过两种方式获取的是同一个对象。我们写代码来验证下:

package com.peterjxl.servletcontext;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@WebServlet("/ServletContextDemo1")
public class ServletContextDemo1 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 演示获取ServletContext

        // 1. 通过`request`对象获取
        ServletContext context1 = req.getServletContext();

        // 2. 通过`HttpServlet`获取
        ServletContext context2 = this.getServletContext();

        System.out.println("context1 == context2: " + (context1 == context2));
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

‍ 重启 Tomcat,访问 http://localhost: 8080/hello/ServletContextDemo1,可以看到控制台运行结果是 true

context1 == context2: true
1

# ServletContext 的功能

主要有如下功能:

  1. 获取 MIME 类型(最常用)
  2. 域对象:共享数据
  3. 获取文件的真实(服务器)路径

# 获取 MIME 类型

什么是 MIME 类型:在互联网通信过程中定义的一种文件数据类型,例如文本类型,图片类型。

这个 MIME 类型有什么用?在响应消息有有个响应头是 Content-type,就是告诉浏览器响应体是什么类型的数据,浏览器根据这个来展示数据

格式: 大类型/小类型,例如 text/html、image/jpeg

获取方法:String getMimeType(String file)。为什么能这样获取?因为 MIME 类型都是存储在服务器里的,而 ServletContext 可以与服务器通信。

我们打开 Tomcat 的安装目录,然后打开 conf/web.xml 文件,这个文件是所有项目的 web.xml 的祖先,可以认为各个项目的 web.xml 文件都继承了它。

以 apache-tomcat-9.0.73\conf\web.xml 为例,从 649 行开始,定义了一大堆的 MIME 类型:

<mime-mapping>
    <extension>123</extension>
    <mime-type>application/vnd.lotus-1-2-3</mime-type>
</mime-mapping>
<mime-mapping>
    <extension>3dml</extension>
    <mime-type>text/vnd.in3d.3dml</mime-type>
</mime-mapping>
<mime-mapping>
    <extension>3ds</extension>
    <mime-type>image/x-3ds</mime-type>
</mime-mapping>
<mime-mapping>
    <extension>3g2</extension>
    <mime-type>video/3gpp2</mime-type>
</mime-mapping>
<mime-mapping>
    <extension>3gp</extension>
    <mime-type>video/3gpp</mime-type>
</mime-mapping>
<mime-mapping>
    <extension>7z</extension>
    <mime-type>application/x-7z-compressed</mime-type>
</mime-mapping>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

‍ extension 标签是后缀名,然后 mime-type 是对应的 MIME 类型。我们写个代码来演示下:

package com.peterjxl.servletcontext;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@WebServlet("/ServletContextDemo2")
public class ServletContextDemo2 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 演示获取MIME
        ServletContext servletContext = this.getServletContext();

        String filename = "a.jpg";
        String mimeType = servletContext.getMimeType(filename);
        System.out.println("mimeType: " + mimeType);

    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

‍ 重启 Tomcat,访问 http://localhost: 8080/hello/ServletContextDemo2,IDE 里的输出:

mimeType: image/jpeg
1

# 域对象:共享数据

域对象都有如下方法,用来共享数据:

  1. setAttribute(String name,Object value)
  2. getAttribute(String name)
  3. removeAttribute(String name)

域对象 ServletContext 范围:所有用户的所有请求。而一个 request 域对象的范围只有在一次请求中。我们写个代码来演示下: ‍ 首先在 ServletContextDemo3 里设置一个数据:

package com.peterjxl.servletcontext;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@WebServlet("/ServletContextDemo3")
public class ServletContextDemo3 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 演示共享数据

        // 2. 通过HttpServlet获取servletContext
        ServletContext servletContext = this.getServletContext();
        servletContext.setAttribute("msg", "fukme");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

然后在 ServletContextDemo4 中获取数据:

package com.peterjxl.servletcontext;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@WebServlet("/ServletContextDemo4")
public class ServletContextDemo4 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 演示获取MIME

        // 2. 通过HttpServlet获取servletContext
        ServletContext servletContext = this.getServletContext();
        Object msg = servletContext.getAttribute("msg");
        System.out.println(msg);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

重启 Tomcat,先访问 ServletContextDemo3,然后访问 ServletContextDemo4;虽然两个是独立的 Servlet,但是可以看到 ServletContextDemo4 能成功获取数据,这说明 ServletContext 能共享数据。

但是我们比较少用 ServletContext 共享,这是因为所有 Servlet 都能操作它,容易冲突;并且容易使得 ServletContext 对象变的臃肿。

# 获取文件的真实(服务器)路径

我们开发项目的时候,一般不会在服务器上面开发,而是在本地开发,开发完后部署到服务器上。也可以说是在本地工作空间中开发;

此时就有一个问题:如果要返回一个文件给用户,文件路径要怎么定义?因为部署到服务器上后,服务器的路径一开始是难以确定的;本地开发的话,文件路径也难以确定,即使确定了,后期一旦换个目录,又要改文件路径的话,非常麻烦。

此时,我们就可以将文件放到 web 目录下,然后通过 ServletContext 获取!

ServletContext 有一个获取文件路径的方法:String getRealPath(String path) ‍ 我们在 src 目录下新建一个 a.txt 文件,web 目录下新建一个 b.txt 文件,在 WEB-INF 目录下新建一个 c.txt 文件,此时项目结构如下:

然后我们可以通过 getRealPath 方法获取文件的路径:

ServletContext servletContext = this.getServletContext();
String realPath = servletContext.getRealPath("/b.txt");
System.out.println(realPath);
1
2
3

‍ 最后,我们就可以 File 对象操作文件了:

File file = new File(realPath);
1

‍ 重启 Tomcat,我们可以看到工作空间目录是这个(每个人的工作空间目录可能不一样):

Using CATALINA_BASE:   "C:\Users\peterjxl\AppData\Local\JetBrains\IntelliJIdea2022.3\tomcat\f48a6060-bf20-4710-adb8-4ae1308d09c7"
1

我们打开这个目录,并打开 conf/Catalina/localhost/hello.xml 文件:可以看到项目的文件是在这里:D:\Projects\LearnJavaWeb\out\artifacts\LearnJavaWeb_war_exploded。

<Context path="/hello" docBase="D:\Projects\LearnJavaWeb\out\artifacts\LearnJavaWeb_war_exploded" />
1

我们访问 http://localhost: 8080/hello/ServletContextDemo5,可以看到打印的路径为:

D:\Projects\LearnJavaWeb\out\artifacts\LearnJavaWeb_war_exploded\b.txt
1

同理,如果想获取 WEB-INF 目录下的路径:

String c = context.getRealPath("/WEB-INF/c.txt");//WEB-INF目录下的资源访问
System.out.println(c);
1
2

如果想要获取 src 目录下的文件路径:可以这样获取:

String a = context.getRealPath("/WEB-INF/classes/a.txt");//src目录下的资源访问
System.out.println(a);
1
2

‍ 这是因为 src 目录下的会被复制到/WEB-INF/classes 下

‍

中文文件问题。解决思路:

  1. 获取客户端使用的浏览器版本信息
  2. 根据不同的版本信息,设置 filename 的编码方式不同
上次更新: 2025/6/3 09:31:54
验证码案例
文件下载案例

← 验证码案例 文件下载案例→

最近更新
01
新闻合订本 2025-10
10-31
02
2025 年 10 月记
10-30
03
用 AI 批量优化思源笔记排版
10-15
更多文章>
Theme by Vdoing | Copyright © 2022-2025 | 粤 ICP 备 2022067627 号 -1 | 粤公网安备 44011302003646 号 | 点击查看十年之约
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式