• 使用Spring Boot注册整合方式整合Servlet三大组件


    在Spring Boot中,使用组件注册方式整合内嵌Servlet容器的Servlet、Filter、Listener三大组件时,只需将这些自定义组件通过ServletRegistrationBean、FilterRegistrationBean、ServletListenerRegistrationBean类注册到容器中即可,这些类相当于将组件配置在web.xml中。

    1. 使用组件注册方式整合Servlet

    (1)创建自定义Servlet类。在chapter05项目中创建名为com.itheima.servletComponent的包,并在该包下创建一个自定义Servlet类MyServlet,内容如文件1所示。

    文件1 MyServlet.java

    import org.springframework.stereotype.Component;
         import javax.servlet.ServletException;
         import javax.servlet.http.*;
         import java.io.IOException;
         /**
          * 自定义Servlet类
         */
         @Component
         public class MyServlet extends HttpServlet {
             @Override
             protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
                                                             throws ServletException, IOException {
                 this.doPost(req, resp);
             }
             @Override
             protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
                                                              throws ServletException, IOException {
                 resp.getWriter().write("hello MyServlet");
             }
         }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    文件1中,使用@Component注解将MyServlet类作为组件注入Spring容器。MyServlet类继承自HttpServlet,通过HttpServletResponse对象向页面输出“hello MyServlet”。

    (2)创建Servlet组件配置类。在项目com.itheima.config包下创建一个Servlet组件配置类ServletConfig,用来对Servlet相关组件进行注册,内容如文件2所示。

    文件2 ServletConfig.java

     import com.itheima.servletComponent.MyServlet;
         import org.springframework.boot.web.servlet.ServletRegistrationBean;
         import org.springframework.context.annotation.Bean;
         import org.springframework.context.annotation.Configuration;
         /**
          * 嵌入式Servlet容器三大组件配置
         */
         @Configuration
         public class ServletConfig {
             // 注册Servlet组件
             @Bean
             public ServletRegistrationBean getServlet(MyServlet myServlet){
                 ServletRegistrationBean registrationBean = 
                                              new ServletRegistrationBean(myServlet,"/myServlet");
                 return registrationBean;
             }
         }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    文件2中,使用@Configuration注解定义了一个Servlet组件配置类ServletConfig,并添加了一个getServlet(MyServlet myServlet)方法,通过组件注册的方式注册自定义的MyServlet组件。在注册自定义的MyServlet组件时,指定了匹配路径为“/myServlet”,并使用@Bean注解将重新组装的ServletRegistrationBean类对象作为Bean组件返回。

    启动项目进行测试。项目启动成功后,在浏览器上访问“http://localhost:8080/myServlet”,效果如图所示。
    在这里插入图片描述
    从图中可以看出,浏览器能够访问myServlet并正常显示数据,说明Spring Boot成功整合了Servlet组件。

    1. 使用组件注册方式整合Filter

    (1) 创建自定义Filter类。在com.itheima.servletComponent包下创建一个类MyFilter,内容如文件3所示。

    文件3 MyFilter.java

    import org.springframework.stereotype.Component;
         import javax.servlet.*;
         import java.io.IOException;
         /**
          *  自定义Filter类
          */
         @Component
         public class MyFilter implements Filter {
             @Override
             public void init(FilterConfig filterConfig) throws ServletException {   }
             @Override
             public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                                    FilterChain filterChain) throws IOException, ServletException {
                 System.out.println("hello MyFilter");
                 filterChain.doFilter(servletRequest,servletResponse);
             }
             @Override
             public void destroy() {   }
         }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    文件3中,使用@Component注解将当前MyFilter类作为组件注入到Spring容器中。MyFilter类实现Filter接口,并重写了init()、doFilter()和destroy()方法,在doFilter()方法中向控制台打印了“hello MyFilter”字符串。

    (1) 向Servlet组件配置类注册自定义Filter类。打开之前创建的Servlet组件配置类ServletConfig,将该自定义Filter类使用组件注册方式进行注册,示例代码如下。

    // 注册Filter组件
    @Bean
    public FilterRegistrationBean getFilter(MyFilter filter){
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
        registrationBean.setUrlPatterns(Arrays.asList("/toLoginPage","/myFilter"));
        return registrationBean;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    上述代码中,使用组件注册方式注册自定义的MyFilter类。在getFilter(MyFilter filter)方法中,使用setUrlPatterns(Arrays.asList(“/toLoginPage”,“/myFilter”))方法定义了过滤的请求路径为“/toLoginPage”和“/myFilter”,同时使用@Bean注解将当前组装好的FilterRegistrationBean对象作为Bean组件返回。

    完成Filter的自定义配置后启动项目,项目启动成功后,在浏览器上访问“http://localhost:8080/myFilter”查看控制台打印效果(由于没有编写对应路径的请求处理方法,所以浏览器会出现404错误页面,这里重点关注控制台即可),具体如图所示。
    在这里插入图片描述
    在图中,浏览器访问“http://localhost:8080/myFilter”时控制台打印出了自定义Filter中定义的输出语句“hello MyFilter”,这也就说明Spring Boot整合自定义Filter组件成功。

    1. 使用组件注册方式整合Listener

    (1)创建自定义Listener类。在com.itheima.servletComponent包下创建一个类MyListener,内容如文件4所示。

    文件4 MyListener.java

    import org.springframework.stereotype.Component;
         import javax.servlet.ServletContextEvent;
         import javax.servlet.ServletContextListener;
         /**
          *  自定义Listener类
         */
         @Component
         public class MyListener implements ServletContextListener {
             @Override
             public void contextInitialized(ServletContextEvent servletContextEvent) {
                 System.out.println("contextInitialized ...");
             }
             @Override
             public void contextDestroyed(ServletContextEvent servletContextEvent) {
                 System.out.println("contextDestroyed ...");
             }
         }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    文件4中,使用@Component注解将MyListener类作为组件注册到Spring容器中。Listener类实现了ServletContextListener接口,并重写了contextInitialized()和contextDestroyed()方法。

    需要说明的是,Servlet容器提供了很多Listener接口,例如ServletRequestListener、HttpSessionListener、ServletContextListener等,我们在自定义Listener类时要根据自身需求选择实现这些接口,这里为了方便演示,直接实现了ServletContextListener接口。

    (2)向Servlet组件配置类注册自定义Listener类。打开之前创建的Servlet组件配置类ServletConfig,将该自定义Listener类使用组件注册方式进行注册,示例代码如下。

    // 注册Listener组件
    @Bean
    public ServletListenerRegistrationBean getServletListener(MyListener myListener){
        ServletListenerRegistrationBean registrationBean = 
    new ServletListenerRegistrationBean(myListener);
        return registrationBean;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    上述代码中,使用组件注册方式注册了一个自定义的MyListener类,在getServletListener()方法中,使用了@Bean注解将当前组装好的FilterRegistrationBean对象作为Bean组件返回。

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

    细心的读者可能发现,将自定义的Servlet组件配置类ServletConfig全部注释并重启项目后,自定义的Servlet、Filter、Listener组件仍然生效。出现这种情况的主要原因是:嵌入式Servlet容器对Servlet、Filter、Listener组件进行了自动化识别和配置,而自定义的Servlet、Filter、Listener都继承/实现了对应的类/接口,同时自定义的Servlet、Filter、Listener组件都使用了@Component注解,这些组件会被自动扫描为Spring组件。

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

    Java基础入门:

    java零基础自学首Java入门教程(含Java项目和Java真题)

    Javaweb核心基础

    JavaWeb基础教程,Java web从入门到企业实战完整版

    Spring全套教程,入门到精通

    Spring视频教程,全面深度讲解spring5底层原理

    SSM框架教程:

    SSM框架教程_Spring+SpringMVC+Maven高级+Spring

    SpringBoot2全套视频教程:

    SpringBoot2全套视频教程,springboot零基础到项目实战

  • 相关阅读:
    limux入门3—磁盘与分区管理
    洛谷基础题练习5
    Actors 基于消息驱动的异步编程模型
    理解SpringBoot的自动装配
    Visopsys 0.92 发布
    C++ vs Rust vs Go性能
    wpf使用CefSharp.OffScreen模拟网页登录,并获取身份cookie
    Python语句和循环
    Nginx入门+实战
    k8s中几个基本概念的理解,pod,service,deployment,ingress的使用场景
  • 原文地址:https://blog.csdn.net/Aa112233aA1/article/details/126263205