• SpringBoot-42-注册Web原生组件


    13.Spring Boot注册Web原生组件

    • Spring Boot 默认以 Jar 包方式部署的,默认没有 web.xml,因此无法再像以前一样通过 web.xml 配置来使用 Servlet 、Filter、Listener,但 Spring Boot 提供了 2 种方式来注册这些 Web 原生组件。

      • 通过组件扫描注册
      • 使用 RegistrationBean 注册
    13.1 通过组件扫描注册
    • Servlet 3.0 提供了以下 3 个注解:

      • @WebServlet:用于声明一个 Servlet;
      • @WebFilter:用于声明一个 Filter;
      • @WebListener:用于声明一个 Listener。
    • 这些注解可直接标注在对应组件上,它们与在 web.xml 中的配置意义相同。每个注解都具有与 web.xml 对应的属性,可直接配置,省去了配置 web.xml 的繁琐。

    • 想要在 SpringBoot 中注册这些原生 Web 组件,可以使用 @ServletComponentScan 注解实现,该注解可以扫描标记 @WebServlet、@WebFilter 和 @WebListener 三个注解的组件类,并将它们注册到容器中。

    注意:@ServletComponentScan 注解只能标记在启动类或配置类上。

    • 例子:创建springboot项目,配置web,devtools依赖
    • 使用 @WebServlet 注解声明一个自定义的 Servlet

    注意请求的方式get方式,返回结果写到doGet方法中,否则会报页面405错误”Method Not Allowed“。

    package com.example.demoweb.config;
    
    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;
    import java.io.PrintWriter;
    
    //使用 @WebServlet 注解声明一个 Servlet
    @WebServlet(name="myServlet",urlPatterns = "/myServlet")
    public class MyServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            resp.setContentType("text/html;charset=UTF-8");
            PrintWriter writer = resp.getWriter();
            writer.write("Spring Boot Servlet");
            writer.close();
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
           doGet(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
    • 使用 @WebFilter 注解声明一个自定义的 Filter
    package com.example.demoweb.config;
    
    
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import java.io.IOException;
    
    //使用 @WebFilter注解声明一个自定义的 Filter
    @WebFilter(urlPatterns = ("/myServlet"))
    public class MyFiler implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("过滤器初始化");
        }
    
        @Override
        public void destroy() {
            System.out.println("过滤器销毁");
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            System.out.println("MyFiler doFilter");
            chain.doFilter(request, response);
        }
    }
    
    • 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
    • 使用 @WebListener 注解声明一个自定义的 Listener
    package com.example.demoweb.config;
    
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    import javax.servlet.annotation.WebListener;
    
    //使用 @WebListener 注解声明一个自定义的 Listener
    @WebListener
    public class MyListener implements ServletContextListener {
    
        @Override
        public void contextInitialized(ServletContextEvent sce) {
            System.out.println("MyListener 监听到 ServletContext 初始化");
        }
    
        @Override
        public void contextDestroyed(ServletContextEvent sce) {
            System.out.println("MyListener 监听到 ServletContext 销毁");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 在启动类上使用 @ServletComponentScan 注解,扫描以上刚刚声明的 Servlet、Filter 和 Listener,并将它们注册到容器中使用
    @SpringBootApplication
    @ServletComponentScan
    public class DemoWebApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(DemoWebApplication.class, args);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 启动 Spring Boot,控制台日志出入如下

    在这里插入图片描述

    • 可以看出,自定义的过滤器 Filter 和 监听器 Listener 都已经生效

    • 然后访问http://localhost:8080/myServlet,页面显示信息,自定义的 Servlet 也已经生效了

    在这里插入图片描述

    13.2 使用 RegistrationBean 注册
    • 可以在配置类中使用 RegistrationBean 来注册原生 Web 组件,此方式相较于注解方式要繁琐一些。使用这种方式注册的原生 Web 组件,不再需要使用 @WebServlet 、@WebListener 和 @WebListener 等注解。

    • RegistrationBean 是个抽象类,负责将组件注册到 Servlet 容器中,Spring 提供了三个它的实现类,分别用来注册 Servlet、Filter 和 Listener。

      • ServletRegistrationBean:Servlet 的注册类
      • FilterRegistrationBean:Filter 的注册类
      • ServletListenerRegistrationBean:Listener 的注册类
    • 我们可以在配置类中,使用 @Bean 注解将 ServletRegistrationBean、FilterRegistrationBean 和 ServletListenerRegistrationBean 添加 Spring 容器中,并通过它们将我们自定义的 Servlet、Filter 和 Listener 组件注册到容器中使用。

    • 沿用上面的例子,将自定义的 Servlet、Filter 和 Listener上的@WebXXX注解和启动类上的@ServletComponentScan注释掉

    • 创建一个配置类 MyConfig,使用 @Bean 注解将 ServletRegistrationBean、FilterRegistrationBean 和 ServletListenerRegistrationBean 添加到 Spring 容器中,并分别使用它们注册我们自定义的 Servlet、Filter 和 Listener

    package com.example.demoweb.config;
    
    import org.springframework.boot.web.servlet.FilterRegistrationBean;
    import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
    import org.springframework.boot.web.servlet.ServletRegistrationBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import java.util.Arrays;
    
    /**
     * @author CNCLUKZK
     * @create 2022/8/22-21:53
     */
    @Configuration
    public class MyConfig {
        //注册 servlet
        @Bean
        public ServletRegistrationBean servletRegistrationBean(){
            MyServlet myServlet = new MyServlet();
            return new ServletRegistrationBean(myServlet,"/helloServlet");
        }
    
        //注册过滤器
        @Bean
        public FilterRegistrationBean filterRegistrationBean(){
            MyFiler myFiler = new MyFiler();
            FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(myFiler);
            //注册该过滤器需要过滤的 url
            filterRegistrationBean.setUrlPatterns(Arrays.asList("/helloServlet"));
            return filterRegistrationBean;
        }
    
        //注册监听器
        @Bean
        public ServletListenerRegistrationBean servletListenerRegistrationBean(){
            MyListener myListener = new MyListener();
            return new ServletListenerRegistrationBean(myListener);
        }
    }
    
    • 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
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 启动服务,控制台日志出入如下。由此可知,自定义的过滤器 Filter 和监听器 Listener 都已经生效

    在这里插入图片描述

    • 然后访问http://localhost:8080/helloServlet,页面显示信息,自定义的 Servlet 也已经生效了

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s2b5yOGE-1662443587521)(../typora-user-images/image-20220822220424524.png)]

    下一篇:SpringBoot-43-文件上传
  • 相关阅读:
    From Java To Kotlin:空安全、扩展、函数、Lambda很详细,这次终于懂了
    LTSPICE仿真那些事
    nodejs卸载和安装教程
    详解设计模式:工厂方法模式
    ASPICE与ISO 21434:汽车软件与网络安全标准的协同与互补
    JavaEE平台技术——Spring和Spring Boot
    安装anaconda3,并搭建一个python3.10开发环境【AI深度学习环境搭建】
    迪杰斯特拉(Dijkstra)算法
    C# TextBox如何变成多行且右边可以上下拉动
    netty入门
  • 原文地址:https://blog.csdn.net/weixin_42045639/article/details/126723657