Spring Boot | Spring Boot 整合 “Servlet三大组件“ ( Servlet / Filter / Listene )

目录:

  • Spring Boot 整合 "Servlet三大组件" :
    • 1. 使用 "组件注册" 的方式 "整合Servlet三大组件" ( 实际操作为 : 创建自定义的"三大组件"对象 + 结合刚创建"的自定义组件对象"来 将 XxxRegistrationBean对象 通过”配置类“的方式加入到 IOC容器中 )
      • 使用 "组件注册" 方式 "整合Servlet"
      • 使用 "组件注册" 方式 "整合Filter / 过滤器"
      • 使用 "组件注册" 方式 "整合Listener / 监听器"
    • 2. 使用 "路径扫描" 的方式 "整合Servlet三大组件" ( 就是通过 "注解" 的方式来"整合Servlet三大组件" )
      • 使用 "路径扫描 / 注解" 方式 "整合Servlet"
      • 使用 "路径扫描 / 注解" 方式 "整合Filter"
      • 使用 "路径扫描 / 注解" 方式 "整合Listene"

Spring Boot 整合 “Servlet三大组件” :

在这里插入图片描述

作者简介 :一只大皮卡丘,计算机专业学生,正在努力学习、努力敲代码中! 让我们一起继续努力学习!

该文章参考学习教材为:
《Spring Boot企业级开发教程》 黑马程序员 / 编著
文章以课本知识点 + 代码为主线,结合自己看书学习过程中的理解和感悟 ,最终成就了该文章

文章用于本人学习使用 , 同时希望能帮助大家。
欢迎大家点赞👍 收藏⭐ 关注💖哦!!!

(侵权可联系我,进行删除,如果雷同,纯属巧合)


  • 进行 Servlet开发时,通常首先自定义ServletFilter ( 过滤器 )、Listener ( 监听器 ) 三大组件,然后在文件 web.xml 中进行配置,而 Spring Boot 使用的是 内嵌式Servlet容器没有提供外部配置文件 web.xml ,那么Spring Boot是如何整合Servlet相关组件呢?
  • Spring Boot提供 了 ① 组件注册② 路径扫描两种方式整合Servlet三大组件 ( ServletFilterListener ),接下来将对分别对这
    两种整合方式进行详细讲解

1. 使用 “组件注册” 的方式 “整合Servlet三大组件” ( 实际操作为 : 创建自定义的"三大组件"对象 + 结合刚创建"的自定义组件对象"来 将 XxxRegistrationBean对象 通过”配置类“的方式加入到 IOC容器中 )

  • Spring Boot中,使用 组件注册 方式 整合内嵌Servlet容器ServletFilterListener三大组件时,只需这些 自定义组件 ( 即为自定义的“Servlet三大对象” ) 通过 ServletRegistrationBeanFilterRegistrationBeanServletListenerRegistrationBean类 注册容器 中即可。

使用 “组件注册” 方式 “整合Servlet”

  • 使用 “组件注册” 方式 “整合Servlet” :

    具体操作为 :

    自定义一个Servlet对象 ( 该对象用于 ServletRegistrationBean对象中 )

    通过 配置类的方式将ServletRegistrationBean对象 加入到IOC容器中,通过以上操作实现了 SpringBoot中整合 “Servlet”

在这里插入图片描述


MyServlet.java :

package com.myh.chapter_11.config;import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;import java.io.IOException;/***  SpringBoot中通过“注册组件”的方式来整合Servlet三大组件*  即通过创建XxxRegistrationBean对象并将其加入到IOC容器中的方式来在SpringBoot中整合Servlet的三大组件*/
@Component //加入到IOC容器中
public class MyServlet extends HttpServlet { ///*doGet()方法*/@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}/*dopost方法*/@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//当url访问该Servlet中的doPost()方法会执行方法体中的代码//客户端(如浏览器)向Servlet发送请求并收到响应时,它会看到响应的内容是 "hello MyServlet" 这个字符串。response.getWriter().write("hello MyServlet");}
}

ServletConfig.java :

package com.myh.chapter_11.config;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration //将该类标记为"配置类"
public class ServletConfig { //Serlvet配置类@Autowiredprivate MyServlet myServlet;@Bean //将给方法的返回值对象加入到IOC容器中//在SpringBoot中注册XxxRegistrationBean组件/对象public ServletRegistrationBean getServlet() {/*/myServlet 这个请求映射到对应的Servlet对象上*/ServletRegistrationBean servletRegistrationBean =new ServletRegistrationBean(myServlet,"/myServlet");return servletRegistrationBean;}
}

启动项目进行测试。项目启动成功后,在浏览器上访问 http://localhost:8080/mySerlvet , 效果如下图所示
在这里插入图片描述

上图可以看出,浏览器能访问/MyServlet正常显示数据,说明SpringBoot 成功整合Servlet组件

使用 “组件注册” 方式 “整合Filter / 过滤器”

  • 使用 “组件注册” 方式 “整合Filter” :

    具体操作为 :

    自定义一个Filter对象 ( 该对象用于 ServletRegistrationBean对象 中 )

    通过 配置类的方式将FilterRegistrationBean对象 加入到IOC容器中 ,通过以上操作实现了 SpringBoot中整合 “Filter”

在这里插入图片描述

MyFilter.java :

package com.myh.chapter_11.config;import jakarta.servlet.*;
import org.springframework.stereotype.Component;import java.io.IOException;@Component //加入到IOC容器中
public class MyFilter implements Filter { //实现 Filter/过滤器接口@Overridepublic void init(FilterConfig filterConfig) throws ServletException {Filter.super.init(filterConfig);}/***  doFilter()方法在“请求处理之前”被执行,就是一个url请求,想到达doFilter()方法,再到达对应的Servlet组件的方法*/@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {//对url请求进行过滤,url请求先在doFilter()方法中拦截,如被放行,才会接着去执行Servlet中的方法System.out.println("hello MyFilter");//将请求和响应对象传递给过滤器链中的下一个实体,这个实体可以是一个过滤器,或者是最终的Servlet或JSP页面filterChain.doFilter(servletRequest, servletResponse);}@Overridepublic void destroy() {Filter.super.destroy();} //自定义“过滤器”/Filter类}

ServletConfig.java :

package com.myh.chapter_11.config;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.Arrays;@Configuration //将该类标记为"配置类"
public class ServletConfig { //Serlvet配置类@Autowiredprivate MyFilter myFilter;@Beanpublic FilterRegistrationBean getFilter() { //将Filter组件加入到IOC容器中FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(myFilter);//设置过滤器要过滤的url路径filterRegistrationBean.setUrlPatterns(Arrays.asList("/toLoginPage","/myFilter"));return filterRegistrationBean;}}

上述代码中,使用 组件注册 方式 注册自定义MyFilter类。在 getFilter( MyFilter filter ) 方法中,使 setUrlPatterns(Arrays.asList(“/toLoginPage”,“/myFilter”)) 方法定义了 过滤的请求路径 为 “/toLoginPage”和“/myFilter’”。


启动项目项目启动成功后,在浏览器上访问 http://localhost:8080/myFilter 查看 控制台打印效果由于没有编写对应路径请求处理方法,所以浏览器会出现404错误页面,这里 重点关注控制台即可),具体如下图所示

在这里插入图片描述

从上图可以看出控制台中打印了自定义Filter中的输出语句 “hello MyFilter”,这说明 SpringBoot整合自定义Filter组件成功

使用 “组件注册” 方式 “整合Listener / 监听器”

  • 使用 “组件注册” 方式 “整合Listener” :

    具体操作为 :

    自定义一个Listener对象 ( 该对象用于 ServletListenerRegistrationBean对象 中 )

    通过 配置类的方式将 ServletListenerRegistrationBean对象 加入到IOC容器中 ,通过以上操作实现了 SpringBoot中整合 “Listener”

在这里插入图片描述

MyListener.java :

package com.myh.chapter_11.config;import jakarta.servlet.ServletContextEvent;
import jakarta.servlet.ServletContextListener;
import org.springframework.stereotype.Component;@Component
public class MyListener implements ServletContextListener { //自定义的“监听器”/Listener 对象/** contextInitialized()方法是Web应用程序启动时被执行。* 该方法的主要用途是对系统的全局变量、配置参数等进行初始化,确保系统在正常运行之前处于一个良好的状态*/@Overridepublic void contextInitialized(ServletContextEvent sce) { //该方法子啊web应用程序启动时被执行System.out.println("contextInitialized.....");}/***  contextDestroyed()方法在web应用程序的"生命周期结束"时/ web应用程序“销毁”时被执行*/@Overridepublic void contextDestroyed(ServletContextEvent sce) { //该方法在web应用程序的"生命周期结束"时被执行System.out.println("contextInitialized.....");}
}

需要说明的是,Servlet容器提供了很多 Listener 接口,例如 ServletRequestListenerHtpSessionListenerServletContextListener 等,我们在自定义 Listener类时要根据自身需求选择实现对应接口


ServletConfig.java :

package com.myh.chapter_11.config;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.Arrays;@Configuration //将该类标记为"配置类"
public class ServletConfig { //Serlvet配置类@Autowiredprivate MyListener myListener;@Beanpublic ServletListenerRegistrationBean getListener() {ServletListenerRegistrationBean servletListenerRegistrationBean =new ServletListenerRegistrationBean(myListener);return servletListenerRegistrationBean;}}

完成自定义Listener组件注册启动项目,项目启动成功后查看控制合打印效果,效果 如下图所示程序启动成功后控制台打印自定义Listener组件 中定义的输出语句contextInitialized…
在这里插入图片描述

单击 IDEA 中的 Exit 按钮 关闭当前项目(注意,如果直接单击红色按钮强制关闭程序浏览器无法打印关闭监听信息),再次查看控制合打印效果,效果 如下图所示 ,程序成功关闭后,控制台打印出了自定义Listener组件中定义的输出语句 : contextInitialized… 通过效果演示。
在这里插入图片描述

通过上面的代码运行截图展示 :说明了 Spring Boot整合自定义Listener 组件成功


注意点

如果我们将自定义Servlet组件配置类ServletConfig 全部注释并重启项目后,自定义ServletFilterListener组件 “仍然生效”
出现这种情况主要原因 是:
嵌入式Servlet容器ServletFilterListener 组件 进行自动化识别和配置,而自定义ServletFilterListener
继承/实现 了对应的 /接口,同时自定义ServletFilterListener组件都使用了 @Component注解这些组件/对象自动扫描Spring组件


ServletRegistrationBeanFilterRegistrationBeanServletListenerRegistrationBean 这些组件组装配置根本目的 是对一些 请求路径参数进行 初始化设置组装 。假设没有组件注册类,那么自定义Servlet虽然生效无法确定哪个访问路径生效自定义Filter对所有的请求都进行过滤不会出现选择性过滤的情况。 而自定义的Listener没有太大影响,因为定制该组件基本不需要设置什么参数

2. 使用 “路径扫描” 的方式 “整合Servlet三大组件” ( 就是通过 “注解” 的方式来"整合Servlet三大组件" )

  • Spring Boot中,除了使用“组件注册”的方式来"整合Servlet三大组件" ,还可以使用 “路径扫描” 的方式 整合 内嵌式 Servlet容器ServletFilterListener 三大组件时。

  • 使用 “路径扫描" 的方式"整合Servlet三大组件具体操作 为:

    第一步、 在自定义ServletFilterListener 分别添加 : @WebServlet( )注解@WebFilter( )注解@WebListener( )注解

    第二步、在 项目主程序启动类上使用@ServletComponentScan注解 开启“组件扫描” / “注解扫描” 即可。

使用 “路径扫描 / 注解” 方式 “整合Servlet”

创建项目
在这里插入图片描述


MyServlet.Java

package com.myh.chapter_11.config;import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;import java.io.IOException;//通过注解的方式来在SpringBoot中“整合Servlet” ( 就是通过注解的方式来SpringBoot中能使用Servlet )
//将 /annotationMyServlet请求映射到该Servlet类中
@WebServlet("/annotationMyServlet")
public class MyServlet extends HttpServlet {/*doGet()方法*/@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}/*dopost方法*/@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//当url访问该Servlet中的doPost()方法会执行方法体中的代码//客户端(如浏览器)向Servlet发送请求并收到响应时,它会看到响应的内容是 "hello MyServlet" 这个字符串。response.getWriter().write("hello MyServlet(annotaion)");}
}

Chapter11Application.Java ( 项目主程序启动类 ):

package com.myh.chapter_11;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;@SpringBootApplication
@ServletComponentScan //开启基于"注解方式"的"Servlet组件扫描"支持 ( 让整合Servlet的三大组件的注解生效 )
public class Chapter11Application {public static void main(String[] args) {SpringApplication.run(Chapter11Application.class, args);}}

启动项目后,访问http://localhost:8080/annotationMyServlet效果如下所示 ,表示用”路径扫描“的方式 成功整合了Servlet

在这里插入图片描述

使用 “路径扫描 / 注解” 方式 “整合Filter”

创建项目
在这里插入图片描述


MyFilter.Java

package com.myh.chapter_11.config;import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import org.springframework.stereotype.Component;import java.io.IOException;//通过注解的方式来在SpringBoot中“整合Filter” ( 就是通过注解的方式来SpringBoot中能使用Filter )
//将 /annotationMyFilter 和 /annotationLogin 请求映射到该 该Filter(过滤器)类中
@WebFilter(value = {"/annotationMyFilter","/annotationLogin"})
public class MyFilter implements Filter { //实现 Filter/过滤器接口@Overridepublic void init(FilterConfig filterConfig) throws ServletException {Filter.super.init(filterConfig);}/***  doFilter()方法在“请求处理之前”被执行,就是一个url请求,想到达doFilter()方法,再到达对应的Servlet组件的方法*/@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {//对url请求进行过滤,url请求先在doFilter()方法中拦截,如被放行,才会接着去执行Servlet中的方法System.out.println("hello MyFilter(annotaion)");//将请求和响应对象传递给过滤器链中的下一个实体,这个实体可以是一个过滤器,或者是最终的Servlet或JSP页面filterChain.doFilter(servletRequest, servletResponse);}@Overridepublic void destroy() {Filter.super.destroy();} //自定义“过滤器”/Filter类}

Chapter11Application.Java ( 项目主程序启动类 ):

package com.myh.chapter_11;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;@SpringBootApplication
@ServletComponentScan //开启基于"注解方式"的"Servlet组件扫描"支持 ( 让整合Servlet的三大组件的注解生效 )
public class Chapter11Application {public static void main(String[] args) {SpringApplication.run(Chapter11Application.class, args);}}

启动项目后,访问http://localhost:8080/annotationMyFilter效果如下所示 ,表示用”路径扫描“的方式 成功整合了Filter

在这里插入图片描述

使用 “路径扫描 / 注解” 方式 “整合Listene”

创建项目
在这里插入图片描述


MyListener.Java

package com.myh.chapter_11.config;import jakarta.servlet.ServletContextEvent;
import jakarta.servlet.ServletContextListener;
import jakarta.servlet.annotation.WebListener;
import org.springframework.stereotype.Component;//通过注解的方式来在SpringBoot中“整合Listener” ( 就是通过注解的方式来SpringBoot中能使用Listener )
//在web应用程序启动时会执行 contextInitialized()方法 , web应用程序结束/销毁后会执行contextDestroyed()方法
@WebListener
public class MyListener implements ServletContextListener { //自定义的“监听器”/Listener 对象/** contextInitialized()方法是Web应用程序启动时被执行。* 该方法的主要用途是对系统的全局变量、配置参数等进行初始化,确保系统在正常运行之前处于一个良好的状态*/@Overridepublic void contextInitialized(ServletContextEvent sce) { //该方法子啊web应用程序启动时被执行System.out.println("contextInitialized.....(annotaion)");}/***  contextDestroyed()方法在web应用程序的"生命周期结束"时/ web应用程序“销毁”时被执行*/@Overridepublic void contextDestroyed(ServletContextEvent sce) { //该方法在web应用程序的"生命周期结束"时被执行System.out.println("contextInitialized.....(annotaion)");}
}

Chapter11Application.Java ( 项目主程序启动类 ):

package com.myh.chapter_11;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;@SpringBootApplication
@ServletComponentScan //开启基于"注解方式"的"Servlet组件扫描"支持 ( 让整合Servlet的三大组件的注解生效 )
public class Chapter11Application {public static void main(String[] args) {SpringApplication.run(Chapter11Application.class, args);}}

启动项目后,访问http://localhost:8080/annotationMyFilter效果如下所示 ,表示用”路径扫描“的方式 成功整合了Listene

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32H7的Cache学习和应用

STM32H7的Cache学习和应用 啥是Cache?Cache的配置配置 Non-cacheable配置 Write through,read allocate,no write allocate配置 Write back,read allocate,no write allocate配置 Write back,read allocate…

电脑端微信截图文字识别功能效率更高了

近期发现微信中的截图文字识别比QQ中的截图文字识别效率高更高,效果更好。 使用方法: 安装电脑端微信客户端:https://weixin.qq.com/(如果没有下载,可以安装一下) 默认截图组合快捷键是:ALTA (使用下来感觉不是很顺手…

【JavaSE进阶】00-基础语法(13-14章) 01-面向对象 02-数组 03-常用类 04-异常处理

13 第十三章 方法覆盖和多态(Polymorphism)★★★★★ 13.1 章节目标与知识框架 13.1.1 章节目标 理解在什么情况下我们需要进行方法覆盖?掌握在满足什么条件的时候构成方法覆盖?什么是多态,代码怎么写?向上转型和向下转型都是…

pytest常用钩子函数

1、什么叫钩子函数 在Pytest框架中,钩子函数是一种允许用户扩展或者自定义测试执行过程的机制。钩子函数允许用户在测试的不同阶段插入自定义的代码,以实现特定的行为,操作或处理。这种插入式的机制使得Pytest具有高度的灵活性和扩展性。 如…

LeetCode 143. 重排链表

解题思路 相关代码 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val val; }* ListNode(int val, ListNode next) { this.val val; this.next next; }* }*…

海康4G摄像机国标注册失败,接入国标28181视频监控平台失败的问题分析、排查、解决

目录 一、问题现象 (一)背景 (二)在平台端,设备显示在线,通道不能传到平台端 (二)直接把通道接入进来,查看是否,显示请求超时 二、问题分析 &#xff0…

56、巴利亚多利德大学、马德里卡洛斯三世研究所:EEG-Inception-多时间尺度与空间卷积巧妙交叉堆叠,终达SOTA!

本次讲解一下于2020年发表在IEEE TRANSACTIONS ON NEURAL SYSTEMS AND REHABILITATION ENGINEERING上的专门处理EEG信号的EEG-Inception模型,该模型与EEGNet、EEG-ITNet、EEGNex、EEGFBCNet等模型均是专门处理EEG的SOTA。 我看到有很多同学刚入门,不太会…

二叉树练习day.8

235.二叉搜索树的最近公共祖先 链接:. - 力扣(LeetCode) 题目描述: 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共…

Spring Boot 学习(5)——开发流程:快速入门

花了几天的时间,整出个 “hello spring boot”,并且把它从 2 搞到了 3。 纸上得来终觉浅!自己实践出真知!现在再回头来囫囵一遍,加深下印象。回想下从前自觉某一编程语言大都如此,先找到简单示例照着画一遍…

分析染色体级别的基因组装配揭示了六倍体栽培菊花的起源和进化-文献精读-7

Analyses of a chromosome-scale genome assembly reveal the origin and evolution of cultivated chrysanthemum 分析染色体级别的基因组装配揭示了栽培菊花的起源和进化 六倍体植物基因组的文献,各位同仁还有什么有特色的基因组评论区留言~ 摘要 菊花&#xf…

【MIT6.S081】Lab3: page tables(详细解答版)

实验内容网址:https://xv6.dgs.zone/labs/requirements/lab3.html 本实验的代码分支:https://gitee.com/dragonlalala/xv6-labs-2020/tree/pgtbl2/ Print a page table 关键点:递归、三级页表 思路: 用上图来解释三级页表的原理最…

HarmonyOS实战开发-横竖屏切换

介绍 本实例展示如何使用媒体查询,通过ohos.mediaquery 接口完成在不同设备上显示不同的界面效果。 效果预览 使用说明 1.在竖屏设备上,首页展示新闻列表,点击新闻进入详情界面。 2.在横屏设备上,首页左侧展示新闻列表&#x…