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类型、分发请求或写入日志文件。

能够共享数据的对象:

  1. request:只能在一次请求一次响应中进行数据的共享 ===》请求转发
  2. session:只能在一次会话过程中,可以有多次请求和响应
  3. 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 项目单独创建的一个上下文(知上知下贯穿全文)对象。有如下功能:

  1. 可以在多个 s e r v l e t servlet servlet 之间共享数据

    • 存放:setAttribute()

    • 获得:getAttribute()

    • 删除:removeAttribute()

  2. 可以获得当前 Web 项目中的指定资源(文件)

    String path = getRealPath( String string);
    
  3. 将请求从一个 s e r v l e t servlet servlet 转发到服务器上的另一个资源。

    RequestDispatcher requestDispatcher = getRequestDispatcher("/1.jpg");
    requestDispatcher.forward(req,res);
    
  4. 将指定资源的内容包含到当前的响应中。

    requestDispatcher.include(req,res);
    
  5. 读取 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 {

    @Override
    public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {
        // 通过 ServletContext 注册 Servlet
        ServletRegistration.Dynamic myServlet = ctx.addServlet("myServlet", MyServlet.class);
        // 大于0时web容器启动时立即创建
        myServlet.setLoadOnStartup(1);
        // servlet映射路径
        myServlet.addMapping("/myServlet");

        // 通过 ServletContext 注册 Filter
        FilterRegistration.Dynamic myFilter = ctx.addFilter("myFilter", MyFilter.class);
        //REQUEST请求类型 除此之外还有 异步、转发等。。
        myFilter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");

        // 通过 ServletContext 注册 Listener
        ctx.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 {

    @Override
    public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext) throws ServletException {
		//略
    }

}

可以看到最重要的一点:它实现了 ServletContainerInitializer 接口,并将自己注册到了配置文件中去。

在这里插入图片描述

因此,在 Web 容器启动时,SpringServletContainerInitializer 会自动调用onStartup方法配置 S p r i n g Spring SpringWeb 环境。

在这里插入图片描述

除了配置 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 组件。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/912681.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【论文复现】MSA+抑郁症模型总结(三)

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀MSA抑郁症模型 热门研究领域&#xff1a;情感计算的横向发展1. 概述2. 论文地址3. 研究背景4. 主要贡献5. 模型结构和代码6. 数据集介绍7. 性…

使用 Umami 部署博客分析工具

Umami 简介 Umami 是一款开源且注重隐私的网站分析工具&#xff0c;可替代 Google Analytics。它提供网站流量和用户行为等见解&#xff0c;但不使用 Cookie 或收集个人数据&#xff0c;符合隐私法规。Umami 轻巧易用&#xff0c;可自行托管。 如果你有自己的博客&#xff0c;…

JAVA笔记 | ResponseBodyEmitter等异步流式接口快速学习

先简单记录下简单使用跟测试&#xff0c;后续再补充具体&#xff0c;最近有用到&#xff0c;简单来说就是后端(服务端)编写个发射器&#xff0c;实现一次请求&#xff0c;一直向前端客户端发射数据&#xff0c;直到发射器执行完毕&#xff0c;模拟ai一句一句回复的效果 Respon…

在IntelliJ IDEA中创建带子模块的SpringBoot工程

前言 在项目开发中&#xff0c;一个工程往往有若干子工程或模块&#xff0c;所以主工程一般是一个容器&#xff0c;本文介绍在IntelliJ IDEA中创建带多模块的SpringBoot工程的详细步骤。 1、首先打开IntellJ IDEA&#xff08;以下简称IDEA&#xff09;,创建一个新项目。假定新…

【LeetCode】每日一题 2024_11_9 设计相邻元素求和服务(构造,哈希)

前言 每天和你一起刷 LeetCode 每日一题~ LeetCode 启动&#xff01; 题目&#xff1a;设计相邻元素求和服务 近几天不知道力扣发什么疯&#xff0c;每日一题出的太抽象了&#xff0c;我题解是写不了一点了 . . . 今天稍微正常了些&#xff0c;就又来更新了~ 代码与解题思路…

如何搭建企业内部知识库?:打造专属智能体,为企业提供高效智能的知识管理

在当今数据爆炸的时代&#xff0c;虽然AI强大&#xff0c;但常规的AI工具或搜索引擎在面对复杂、专业领域的问题时&#xff0c;可能给出模棱两可的回应&#xff0c;无法满足企业精细化的需求。这就是为什么&#xff0c;企业需要一个专属的AI知识库 —— 它不仅能存储你的数据&a…

胶囊网络、MobileNet、坐标注意力机制的应用

文章目录 摘要Abstract1.胶囊网络1.1 动态路由 2.坐标注意力机制3.MobileNet3.1 深度卷积3.2 逐点卷积3.3 深度可分离卷积3.3.1 深度可分离卷积与标准卷积的对比3.3.2 卷积操作的代码实现3.3.2.1 函数原型3.3.2.2 标准卷积3.3.2.3 分组卷积3.3.2.4 深度可分离卷积 3.4 MobileNe…

一个开源、免费(MIT License)、功能强大、可扩展的电动汽车充电控制器和家庭能源管理系统(带私活源码)

项目介绍 evcc是一个开源、免费&#xff08;MIT License&#xff09;、功能强大、可扩展的电动汽车充电控制器和家庭能源管理系统&#xff0c;支持广泛的设备和品牌&#xff0c;提供简单的用户界面和强大的功能。 功能特点 用户界面&#xff1a;简单且清晰的用户界面。 充电器…

Pr 视频过渡:沉浸式视频

效果面板/视频过渡/沉浸式视频 Video Transitions/Immersive Video Adobe Premiere Pro 的视频过渡效果中&#xff0c;沉浸式视频 Immersive Video效果组主要用于 VR 视频剪辑之间的过渡。 自动 VR 属性 Auto VR Properties是所有 VR 视频过渡效果的通用选项。 默认勾选&#x…

[OpenGL]使用OpenGL实现硬阴影效果

一、简介 本文介绍了如何使用OpenGL实现硬阴影效果&#xff0c;并在最后给出了全部的代码。本文基于[OpenGL]渲染Shadow Map&#xff0c;实现硬阴影的流程如下&#xff1a; 首先&#xff0c;以光源为视角&#xff0c;渲染场景的深度图&#xff0c;将light space中的深度图存储…

成都睿明智科技有限公司抖音电商服务效果如何?

在这个短视频风起云涌的时代&#xff0c;抖音电商以其独特的魅力&#xff0c;成为了众多商家竞相追逐的新蓝海。而在这片波澜壮阔的商海中&#xff0c;成都睿明智科技有限公司犹如一艘稳健的航船&#xff0c;引领着无数企业驶向成功的彼岸。今天&#xff0c;就让我们一起揭开成…

uniapp 实现瀑布流

效果演示 组件下载 瀑布流布局-waterfall - DCloud 插件市场

集合进阶(JAVA笔记第二十九期)

p.s.这是萌新自己自学总结的笔记&#xff0c;如果想学习得更透彻的话还是请去看大佬的讲解 集合基础看这里 目录 集合体系结构单列集合Collection各个方法的注意事项add()remove()contains() Collection三种遍历方式迭代器遍历增强for遍历lambda表达式遍历匿名内部类遍历 Lis…

使用LlamaIndex框架构建RAG应用的基础实践指南

前言 上一篇文章[检索增强生成 Retrieval-Augmented Generation]介绍了什么是 RAG &#xff0c;并详细对比了和大模型微调方式的区别。 目前实现 RAG 的主流框架就是 [LangChain] 和 [LlamaIndex]&#xff0c;LangChain 更适合需要复杂对话流程、上下文管理、以及多步骤任务的…

小程序开发进阶之路-AI编程助手

之前&#xff0c;我独自一人开发了一个名为“心情追忆”的小程序&#xff0c;旨在帮助用户记录日常的心情变化及重要时刻。从项目的构思、设计、前端&#xff08;小程序&#xff09;开发、后端搭建到最终部署&#xff0c;所有环节都由我一人包办。经过一个月的努力&#xff0c;…

Typora导出pdf手动分页和设置字体样式

手动分页 <div style"page-break-after: always;"></div>鼠标点击代码才会显示&#xff0c;不点击会隐藏。导出pdf时&#xff0c;该位置会分页 设置字体大小、加粗、居中、空格 <p style"font-size:30px; font-weight: bold; text-align: cen…

【GCN】 代码详解 (1) 如何运行【pytorch】可运行版本

Graph Convolutional Networks 代码详解 前言0.引言1.环境配置2. 代码的运行2.1 报错处理2.2 运行结果 3.总结 前言 在前文中&#xff0c;已经对图卷积神经网络&#xff08;Graph Convolutional Neural Networks, GCN&#xff09;的理论基础进行了深入探讨。接下来的章节将会进…

基于 PyTorch 从零手搓一个GPT Transformer 对话大模型

一、从零手实现 GPT Transformer 模型架构 近年来&#xff0c;大模型的发展势头迅猛&#xff0c;成为了人工智能领域的研究热点。大模型以其强大的语言理解和生成能力&#xff0c;在自然语言处理、机器翻译、文本生成等多个领域取得了显著的成果。但这些都离不开其背后的核心架…

做口播博主:真人出镜还是用数字人

做口播博主&#xff1a;真人出镜还是用数字人&#xff1f; 背景&#xff1a;数字人“风口”与流量的冷现实 数字人生成的视频逐渐流行&#xff0c;但真正拥有爆款流量的案例却寥寥无几&#xff1b;另一方面&#xff0c;真人出镜的创作又面临镜头感不足和成本高的难题。创作者究…

【C++篇】在秩序与混沌的交响乐中: STL之map容器的哲学探寻

文章目录 C map 容器详解&#xff1a;高效存储与快速查找前言第一章&#xff1a;C map 的概念1.1 map 的定义1.2 map 的特点 第二章&#xff1a;map 的构造方法2.1 常见构造函数2.1.1 示例&#xff1a;不同构造方法 2.2 相关文档 第三章&#xff1a;map 的常用操作3.1 插入操作…