ServletContext介绍
文章目录
- 1、ServletContext对象介绍
- 1_方法介绍
- 2_用例分析
- 2、ServletContainerInitializer
- 1_整体结构
- 2_工作原理
- 3_使用案例
- 3、Spring案例源码分析
- 1_注册DispatcherServlet
- 2_注册配置类
- 3_SpringServletContainerInitializer
- 4_总结
ServletContext 表示上下文对象,属于接口,代表整个 Web 项目,可以使用定义的方法与 S e r v l e t Servlet Servlet容器进行通信。例如,获取文件的MIME类型、分发请求或写入日志文件。
能够共享数据的对象:
- request:只能在一次请求一次响应中进行数据的共享 ===》请求转发
- session:只能在一次会话过程中,可以有多次请求和响应
- ServletContext:只要项目存在就可以共享数据,多次会话,多次请求和响应都可以共享数据:操作整个项目的配置文件
范围大小: ServletContext > session > request
1、ServletContext对象介绍
当 t o m c a t tomcat tomcat 服务器启动的时候,会为每个 Web 项目创建一个唯一的 S e r v l e t C o n t e x t ServletContext ServletContext 对象,该对象代表当前整个 Web 应用项目。
该对象不仅封装了当前 Web 应用的所有信息,而且实现了多个 s e r v l e t servlet servlet 的数据共享。
在 S e r v l e t C o n t e x t ServletContext ServletContext 中可以存放共享数据, S e r v l e t C o n t e x t ServletContext ServletContext 对象是真正的一个全局对象,凡是 Web 容器中的 S e r v l e t Servlet Servlet 都可以访问。
在每个项目中可以有多个 S e r v l e t Servlet Servlet 程序,每个 S e r v l e t Servlet Servlet 程序都是独立的。当前这个项目的配置信息,必须使用描述这个项目的 S e r v l e t C o n t e x t ServletContext ServletContext 对象获取。
1_方法介绍
方法名 | 描述 |
---|---|
setAttribute(String name, Object object) | 向 S e r v l e t C o n t e x t ServletContext ServletContext中存数据 |
getAttribute(String name) | 从 S e r v l e t C o n t e x t ServletContext ServletContext中取数据 |
removeAttribute(name) | 从 S e r v l e t C o n t e x t ServletContext ServletContext中移除数据 |
String getRealPath(String path) | 返回资源文件在服务器文件系统上的真实路径(文件的绝对路径) |
getMimeType(fileName) | 获取服务器中文件类型.txt text/plain .html text/html |
getResourceAsStream(String path) | 获取某个资源的输入流 |
getRequestDispatcher(String path) | 返回一个 RequestDispatcher 对象, 可以使用它将请求转发到指定资源,或者在响应中包含资源。 |
S e r v l e t C o n t e x t ServletContext ServletContext 对象: t o m c a t tomcat tomcat为每一个 Web 项目单独创建的一个上下文(知上知下贯穿全文)对象。有如下功能:
-
可以在多个 s e r v l e t servlet servlet 之间共享数据
-
存放:
setAttribute()
-
获得:
getAttribute()
-
删除:
removeAttribute()
-
-
可以获得当前 Web 项目中的指定资源(文件)
String path = getRealPath( String string);
-
将请求从一个 s e r v l e t servlet servlet 转发到服务器上的另一个资源。
RequestDispatcher requestDispatcher = getRequestDispatcher("/1.jpg"); requestDispatcher.forward(req,res);
-
将指定资源的内容包含到当前的响应中。
requestDispatcher.include(req,res);
-
读取 Web 应用中的资源文件
InputStream resourceStream = context.getResourceAsStream("/WEB-INF/config.properties");
S e r v l e t C o n t e x t ServletContext ServletContext 还提供了如下方法动态注册 S e r v l e t Servlet Servlet、 F i l t e r Filter Filter、 L i s t e n e r Listener Listener以及及初始化参数信息:
方法名 | 描述 |
---|---|
addServlet(String servletName, Servlet servlet) | 动态注册 S e r v l e t Servlet Servlet |
addFilter(String filterName, Filter filter) | 动态注册 F i l t e r Filter Filter |
addListener(String className) | 动态注册 L i s t e n e r Listener Listener |
setInitParameter(String name, String value) | 为 Web 应用设置初始化参数。 |
2_用例分析
需求1:如何获取上下文 S e r v l e t C o n t e x t ServletContext ServletContext 对象。
- 使用HttpServlet类的父类 GenericServlet 中的方法:
getServletContext();
- 通过实现 ServletContextListener 来获取(详见监听器博文)。
代码如下:
/*获取上下文ServletContext对象:使用HttpServlet类的父类 GenericServlet 中的方法:getServletContext();
*/
ServletContext servletContext = getServletContext();
需求2:如何获取服务器中每个文件的路径 ?例如,在当前项目下的web文件夹下放一个1.jpg
的图片,获取其真实路径(绝对路径)。
@WebServlet("/servletContextDemoServlet")
public class ServletContextDemoServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {ServletContext servletContext = getServletContext();//如何获取服务器中每个文件的路径。// 例如,在当前项目下的web文件夹下放一个1.jpg的图片,获取其真实路径(绝对路径)。String realPath = servletContext.getRealPath("/1.jpg");/*输出结果:realPath = E:\WorkAndClass\maven_war_pro\src\main\webapp\1.jpg说明:我们的项目在发布的时候会被打成一个war包,这个war包下的class文件会被放在tomcat下被运行。所以这里获取的真实路径是这个war包下的1.jpg所在的路径。*/System.out.println("realPath = " + realPath);}
}
需求3:获取当前项目下的1.jpg
在服务器中的文件类型。
/*需求3:获取当前项目下的1.jpg在服务器中的文件类型。getMimeType("1.jpg");这里书写获取文件类型的文件名和后缀名即可
*/
String mimeType = servletContext.getMimeType("1.jpg");
System.out.println("mimeType = " + mimeType);//mimeType = image/jpeg
需求4:请求转发,将发往ServletContextDemoServlet
的请求转发到MyServlet
中。
RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher("/MyServlet");
requestDispatcher.forward(request, response);
注意:对于方法 getMimeType("1.jpg")
;这里书写获取文件类型的文件名和后缀名即可
2、ServletContainerInitializer
在 S e r v l e t 3.0 Servlet 3.0 Servlet3.0 规范中,ServletContainerInitializer 接口被引入,用于替代传统的 web.xml
配置方式,允许开发者在 S e r v l e t Servlet Servlet 容器启动时动态地进行 S e r v l e t Servlet Servlet、 F i l t e r Filter Filter 和 L i s t e n e r Listener Listener 的注册与初始化配置。
这种通过编程来实现应用初始化过程的方式具有很大的灵活性,尤其是在现代基于注解和 Java 配置的 Web 应用中,减少了对 web.xml
配置文件的依赖,提供了更强的动态配置能力。
1_整体结构
该接口只有一个方法:
public interface ServletContainerInitializer {public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException;
}
-
Set<Class<?>> c
:此参数表示与当前 Web 应用相关联的所有类。通常,这些类会通过类路径扫描来识别。
开发者可以利用这个参数进行自定义的初始化逻辑,比如扫描特定的注解。
-
ServletContext ctx
:这是 S e r v l e t C o n t e x t ServletContext ServletContext 对象,不再重复介绍。
2_工作原理
ServletContainerInitializer 接口通过反射机制(SPI机制)在 Web 容器启动时进行实例化。
当 Web 容器(如 T o m c a t Tomcat Tomcat)启动时,它会扫描所有部署的应用程序,查找是否有 META-INF/services/javax.servlet.ServletContainerInitializer
文件,该文件中会包含一个实现类的全限定名。
如果这个文件存在,Web 容器启动时会加载其中列出的所有 ServletContainerInitializer 实现类,并调用它们的 onStartup()
方法来初始化 Web 应用。
在onStartup()
方法中,可以通过 S e r v l e t C o n t e x t ServletContext ServletContext 来进行 S e r v l e t Servlet Servlet、 F i l t e r Filter Filter、 L i s t e n e r Listener Listener 等组件的注册。
3_使用案例
1、编写 ServletContainerInitializer 实现类
package com.example.sh;import javax.servlet.*;
import java.util.EnumSet;
import java.util.Set;public class MyServletContainerInitializer implements ServletContainerInitializer {@Overridepublic void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {// 通过 ServletContext 注册 ServletServletRegistration.Dynamic myServlet = ctx.addServlet("myServlet", MyServlet.class);// 大于0时web容器启动时立即创建myServlet.setLoadOnStartup(1);// servlet映射路径myServlet.addMapping("/myServlet");// 通过 ServletContext 注册 FilterFilterRegistration.Dynamic myFilter = ctx.addFilter("myFilter", MyFilter.class);//REQUEST请求类型 除此之外还有 异步、转发等。。myFilter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");// 通过 ServletContext 注册 Listenerctx.addListener(MyListener.class);// 设置 Web 应用的初始化参数ctx.setInitParameter("appVersion", "1.0");}
}
2、注册 ServletContainerInitializer 实现类
在 META-INF/services/javax.servlet.ServletContainerInitializer
文件中添加如下内容:
com.example.sh.MyServletContainerInitializer
3、Spring案例源码分析
在一个典型的 S p r i n g Spring Spring MVC 应用中, S e r v l e t C o n t e x t ServletContext ServletContext 是一个重要的组件,它代表 Web 应用的上下文,提供了访问应用范围内资源和配置的能力。
DispatcherServlet 是 S p r i n g Spring Spring MVC 的前端控制器,处理所有传入的 HTTP 请求,并负责将请求委派给适当的控制器方法。
在这个过程中, S e r v l e t C o n t e x t ServletContext ServletContext 作为 S p r i n g Spring Spring 容器的核心之一,起到了协调和管理作用。
1_注册DispatcherServlet
在 S e r v l e t Servlet Servlet容器配置类的继承类 AbstractDispatcherServletInitializer 中也有与ServletContainerInitializer
中同名的方法onStartup()
:
public static final String DEFAULT_SERVLET_NAME = "dispatcher";
@Override
public void onStartup(ServletContext servletContext) throws ServletException {super.onStartup(servletContext);registerDispatcherServlet(servletContext);
}
在onStartup()
中调用了registerDispatcherServlet
方法,从方法名就可以看出,这个方法是用于注册 DispatcherServlet 的方法:
2_注册配置类
ServletContainerInitializer
的实现类需要通过配置文件来获取类的全限定名进行注册,这在 S p r i n g Spring Spring MVC 中也是一样的。
首先,我们看一下AbstractDispatcherServletInitializer的继承结构:
发现顶级父类是 WebApplicationInitializer
接口:
package org.springframework.web;import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;public interface WebApplicationInitializer {void onStartup(ServletContext servletContext) throws ServletException;
}
在此接口相关的 jar 包中就可以发现对应的配置文件了,如下图(我的版本较高, S e r v l e t 5.0 Servlet5.0 Servlet5.0 以后把javax.servlet
包名改成了jakarta.servlet
,所以名称会略有差别):
文件内容如下:
org.springframework.web.SpringServletContainerInitializer
3_SpringServletContainerInitializer
经过上述分析,最终找到了一个以 S p r i n g Spring Spring 开头的配置类,那么这个类的作用是什么呢?先看结构:
@HandlesTypes(WebApplicationInitializer.class)//容器可以在启动时扫描并收集所有实现了 WebApplicationInitializer 接口的类
public class SpringServletContainerInitializer implements ServletContainerInitializer {@Overridepublic void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext) throws ServletException {//略}}
可以看到最重要的一点:它实现了 ServletContainerInitializer
接口,并将自己注册到了配置文件中去。
因此,在 Web 容器启动时,SpringServletContainerInitializer 会自动调用onStartup
方法配置 S p r i n g Spring Spring 的 Web 环境。
除了配置 DispatcherServlet 外,它其实还会注册 ContextLoaderListener,用于加载 S p r i n g Spring Spring 的根应用上下文。
4_总结
S e r v l e t C o n t e x t ServletContext ServletContext 表示上下文对象,代表整个web项目, t o m c a t tomcat tomcat 一启动就会创建该接口对象,关闭 t o m c a t tomcat tomcat 就会消失
S e r v l e t C o n t e x t ServletContext ServletContext 属于对象,多次会话,多次请求限制,三个域对象范围:ServletContext > HttpSession > HttpServletRequest
S e r v l e t C o n t e x t ServletContext ServletContext 其他作用:
-
获取文件真实路径:
String getRealPath(String path)
参数 path 如果书写的是相对路径相对的是webapp。 -
获取文件的MIME类型:
String getMimeType(String file)
参数 file 只书写文件名 + 后缀名即可,不会判断是否存在。 -
获取请求分发对象:
RequestDispatcher getRequestDispatcher(String path)
参数 path 书写的是资源路径。 -
动态注册 Web 组件。
相关文章:

ServletContext介绍
文章目录 1、ServletContext对象介绍1_方法介绍2_用例分析 2、ServletContainerInitializer1_整体结构2_工作原理3_使用案例 3、Spring案例源码分析1_注册DispatcherServlet2_注册配置类3_SpringServletContainerInitializer 4_总结 ServletContext 表示上下文对象,…...

让AI帮我用java实现EasyExel读取图片—支持WPS嵌入图片
🌈 场景概述 java 小伙伴相信都使用 EasyExcel 以及 POI 库实现过 Excel 批量导入、导出功能,但只有部分人实现过 excel 导入带图片数据的场景。这个技术实现手段网上也有很多案例和demo,最常见的就是通过 XSSFPictureData 来实现。但是在 W…...

C# 实现对指定句柄的窗口进行键盘输入的实现
在C#中实现对指定句柄的窗口进行键盘操作,可以通过多种方式来实现。以下是一篇详细的指南,介绍如何在C#中实现这一功能。 1. 使用Windows API函数 在C#中,我们可以通过P/Invoke调用Windows API来实现对指定窗口的键盘操作。以下是一些关键的…...

深度学习之卷积问题
1 卷积在图像中有什么直观作用 在卷积神经网络中,卷积常用来提取图像的特征,但不同层次的卷积操作提取到的特征类型是不相同的,特征类型粗分如表1所示。 表1 卷积提取的特征类型 卷积层次特征类型浅层卷积边缘特征中层卷积局部特征深…...
yum安装zabbix5.0升级php到74的办法
【背景】 公司时不时有扫描漏洞,之前发现了php漏洞,因开启防火墙,限定IP+端口,暂时躲过升级;现在,老话重提,开启了KPI考核,躲是躲不过去的了,升级吧 【难题】 服务器为centos7,因操作系统问题,只能安装zabbix5.0。当时图省力,官网的办法,都是yum安装,很是简便。…...

JavaWeb合集23-文件上传
二十三 、 文件上传 实现效果:用户点击上传按钮、选择上传的头像,确定自动上传,将上传的文件保存到指定的目录中,并重新命名,生成访问链接,返回给前端进行回显。 1、前端实现 vue3AntDesignVue实现 <tem…...

当AI遇上时尚:未来的衣橱会由机器人来打理吗?
内容概要 在当今这个快速发展的时代,人工智能与时尚的结合正在逐渐改写我们对衣橱管理的认知。传统的衣橱管理常常面临着空间不足、穿搭单调及库存过多等挑战,许多人在挑选服饰时难以做出决策。然而,随着技术的进步,智能推荐和自…...

【初阶数据结构篇】二叉树OJ题
文章目录 须知 💬 欢迎讨论:如果你在学习过程中有任何问题或想法,欢迎在评论区留言,我们一起交流学习。你的支持是我继续创作的动力! 👍 点赞、收藏与分享:觉得这篇文章对你有帮助吗࿱…...

Windows系统中Oracle VM VirtualBox的安装
一.背景 公司安排了师带徒,环境搭建问题一直是初级程序员头疼的事情,我记录一下这些基础的内容,方便初学者。大部分开发者的机器还是windows系统,所以写了怎么安装。 二.版本信息及 操作系统:windows11 家庭版…...
go语言使用总结(持续更新)
整理后的内容如下: 1. 先了解函数签名,再了解传入参数以及调用 函数签名是函数的声明部分,包括函数名、参数列表和返回值列表。理解函数签名是理解函数行为的第一步,尤其是在了解参数类型、参数数量和返回值类型等方面。通过了解…...

如何在Android中自定义property
在Android中创建自定义的属性(Android property)通常用于调试、性能调优或传递应用和系统之间的信息。 以下是如何在Android中创建和使用自定义属性的步骤: 1. 定义属性 在Android中,属性是以“属性名称属性值”形式定义的键值对…...
机器学习5_支持向量机_原问题和对偶问题——MOOC
目录 原问题与对偶问题的定义 定义该原问题的对偶问题如下 在定义了函数 的基础上,对偶问题如下: 综合原问题和对偶问题的定义得到: 定理一 对偶差距(Duality Gap) 强对偶定理(Strong Duality Theo…...

索引的细节
目录 什么是线性 搜索算法? 算法:二进制搜索算法 二进制搜索如何工作? 什么是二叉排序树? 构建二叉排序树 什么是AVL树? AVL树的性能分析 什么是线性 搜索算法? 线性搜索是一种非常简单的搜索算法。在…...

LeetCode 540.有序数组中的单一元素
思路一:hash,键存入元素,值存入次数,然后遍历,不是最优解 思路二:二分查找 假设数组为 [1, 1, 2, 2, 3, 4, 4],其中唯一出现一次的元素是 3。在一个有序数组中,如果没有唯一的元素&…...

【图文】【DIY便签】如何自行编译OPENCV使用动态库
1 去官网下载安装包和源码 下面红色圈中的是源码,绿色圈中的是安装包: 2 配置工具链 安装过程不说了,教程到处都是。编译的话使用CMAKE,配置如下: 上面两个路径分别是: 源码目录编译生成的文件放置的位…...
WordPress文章自动提交Bing搜索引擎:PHP推送脚本教程
随着网站SEO优化的重要性日益增加,将新发布的内容快速提交到搜索引擎显得尤为重要。尤其对于Bing站长平台,自动化推送能让Bing尽快发现和索引我们网站的新内容。本文将详细介绍如何通过PHP脚本自动推送WordPress当天发布的文章至Bing站长平台,确保新文章被Bing及时收录。 前…...
C++题目分享
嗨嗨嗨,我又来更新这个系列了,很久没更新了。让我们看一看有那些有趣的题目: 题目一: 1.以单链表作为存储结构,实现线性表的就地逆置(提示,就地逆置:在不使用额外的数据结构或空间…...

【Spring 框架】初识 Spring
文章目录 前言1. 什么是 Spring2. 什么是 Maven3. 第一个 SpringBoot 项目4. 项目讲解结语 前言 在前面我们一起学习了 JavaSE 的基础知识,随着学习的深入,我们也将逐步介绍 JavaEE 的内容,像 Spring 框架,Mybatis 等等。在本篇博…...

链表(Linkedlist)
序言 我们都了解链表是一种数据的存储结构,在Java使用中逻辑与c,c语言数据结构别无二致,但主要由于Java中不存在指针的说法,从而导致在实现过程中的代码不同,所以在学习的过程中我们无需过于担心,逻辑都是…...

信息安全工程师(79)网络安全测评概况
一、定义与目的 网络安全测评是指参照一定的标准规范要求,通过一系列的技术、管理方法,获取评估对象的网络安全状况信息,并对其给出相应的网络安全情况综合判定。其对象主要为信息系统的组成要素或信息系统自身。网络安全测评的目的是为了提高…...

从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...

Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...

select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
快刀集(1): 一刀斩断视频片头广告
一刀流:用一个简单脚本,秒杀视频片头广告,还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农,平时写代码之余看看电影、补补片,是再正常不过的事。 电影嘛,要沉浸,…...

Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践
在 Kubernetes 集群中,如何在保障应用高可用的同时有效地管理资源,一直是运维人员和开发者关注的重点。随着微服务架构的普及,集群内各个服务的负载波动日趋明显,传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...

Mysql故障排插与环境优化
前置知识点 最上层是一些客户端和连接服务,包含本 sock 通信和大多数jiyukehuduan/服务端工具实现的TCP/IP通信。主要完成一些简介处理、授权认证、及相关的安全方案等。在该层上引入了线程池的概念,为通过安全认证接入的客户端提供线程。同样在该层上可…...

【51单片机】4. 模块化编程与LCD1602Debug
1. 什么是模块化编程 传统编程会将所有函数放在main.c中,如果使用的模块多,一个文件内会有很多代码,不利于组织和管理 模块化编程则是将各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数声明,其他.c文…...