zoukankan      html  css  js  c++  java
  • 02-SpringBoot整合Servlet过滤器监听器

    可以看官网

    http://felord.cn/_doc/_springboot/2.1.5.RELEASE/_book/

    28、开发Web应用程序

     一、SpringBoot整合Servlet

    新建一个项目springboot_web

    新建包controller, 新建MyController文件

     MyController.java

    package xyz.kxq.controller;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class MyController {
        @RequestMapping("hello")
        public String hello(){
            return "hello, springboot";
        }
    }

    运行程序,浏览器访问:

    这就是我们之前搭建web项目最简单的一种方式, 可以集成servlet

    1、Servlet、Filter与Listener

    可以看文档中

    28.4、内嵌Servlet容器支持

     Spring Boot 包含了对内嵌 TomcatJetty 和 Undertow 服务器的支持

    使用servlet可以配置Servlet、Filter、Listener

    • Servlet业务逻辑类
    • Filter 过滤器
    • Listener 监听器

    使用内嵌 servlet 容器时,您可以使用 Spring bean 或者扫描方式来注册 Servlet 规范中的 Servlet、Filter 和所有监听器(比如 HttpSessionListener)。

    任何 ServletFilter 或 *Listener 的 Spring bean 实例都将被注册到内嵌容器中。如果您想引用 application.properties 中的某个值,这可能会特别方便。

    默认情况下,如果上下文只包含单个 Servlet,它将映射到 /。在多个 Servlet bean 的情况下,bean 的名称将用作路径的前缀。Filter 将映射到 /*

    如果基于约定配置的映射不够灵活,您可以使用 ServletRegistrationBeanFilterRegistrationBean 和 ServletListenerRegistrationBean 类来完全控制

    Spring Boot 附带了许多可以定义 Filter bean 的自动配置。以下是部分过滤器及其执行顺序的(顺序值越低,优先级越高):

    Servlet Filter顺序
    OrderedCharacterEncodingFilter Ordered.HIGHEST_PRECEDENCE
    WebMvcMetricsFilter Ordered.HIGHEST_PRECEDENCE + 1
    ErrorPageFilter Ordered.HIGHEST_PRECEDENCE + 1
    HttpTraceFilter Ordered.LOWEST_PRECEDENCE - 10

    通常 Filter bean 无序放置也是安全的。

    如果需要指定顺序,则应避免在 Ordered.HIGHEST_PRECEDENCE 顺序点配置读取请求体的过滤器,因为它的字符编码可能与应用程序的字符编码配置不一致。

    如果一个 Servlet 过滤器包装了请求,则应使用小于或等于 OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER的顺序点对其进行配置。

    2、Servlet上下文初始化

    我们一般刚接触web开发的时候第一个接触的都是servlet, 下面我们来使用springboot来整合servlet

    1. 编写servlet类
      1. 新建包servlet
      2. 新建MyServlet文件
      3. package xyz.kxq.servlet;
        
        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;
        
        @WebServlet(name = "myServlet", urlPatterns = "/srv")
        public class MyServlet extends HttpServlet {
            @Override
            protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                System.out.println("111");
                super.doGet(req, resp);
            }
        
            @Override
            protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                super.doPost(req, resp);
            }
            
        }
    2. 在启动类上添加如下配置
      1. @ServletComponentScan, @SpringBootApplication点进去会有一个@ComponentScan
      2.     会有一个自动扫描的过程
      3.     需要把Servlet注册为当前SpringBoot容器里面的一个bean
      4. package xyz.kxq;
        
        import org.springframework.boot.SpringApplication;
        import org.springframework.boot.autoconfigure.SpringBootApplication;
        import org.springframework.boot.web.servlet.ServletComponentScan;
        import org.springframework.boot.web.servlet.ServletRegistrationBean;
        import org.springframework.context.annotation.Bean;
        import xyz.kxq.servlet.MyServlet;
        
        @SpringBootApplication
        @ServletComponentScan
        public class SpringbootWebApplication {
        
            public static void main(String[] args) {
                SpringApplication.run(SpringbootWebApplication.class, args);
            }
        
            @Bean
            public ServletRegistrationBean<MyServlet> getServletRegistrationBean(){
                ServletRegistrationBean<MyServlet> bean = new ServletRegistrationBean<>(new MyServlet(), "/s2");
                bean.setLoadOnStartup(1);
                return bean;
            }
        getServletRegistrationBean: 获取servlet注册的一个Bean对象,可以加路由(/s2),当配置了urlmappings之后,servlet自己的配置就不会生效了
        bean.setLoadOnStartup: 设置servlet什么时候启动,配置当前类,设置为1了
    3. 启动服务
    4. 访问 http://localhost:8080/myServlet/
      1. 打印结果为
        111
        111
    5. 所以说可以自己写一个servlet类,然后把servlet类注入到springboot里面就ok了。

     二、过滤器

    包下新建filter目录,新建MyFilter文件

    package xyz.kxq.filter;
    
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import java.io.IOException;
    
    @WebFilter(filterName = "MyFilter", urlPatterns = "/filter")
    public class MyFilter implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("init");
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            System.out.println("filter");
            chain.doFilter(request, response);
        }
    }

    重启服务会发现init执行了

    2021-10-21 15:41:40.665  INFO 118196 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 725 ms
    2021-10-21 15:41:40.700  INFO 118196 --- [           main] o.s.boot.web.servlet.RegistrationBean    : Servlet myServlet was not registered (possibly already registered?)
    init
    2021-10-21 15:41:40.929  INFO 118196 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
    2021-10-21 15:41:40.936  INFO 118196 --- [           main] xyz.kxq.SpringbootWebApplication         : Started SpringbootWebApplication in 1.34 seconds (JVM running for 2.217)

    当访问http://localhost:8080/filter, 发现filter执行了

    2021-10-21 15:44:47.008  INFO 118196 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
    2021-10-21 15:44:47.008  INFO 118196 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
    2021-10-21 15:44:47.009  INFO 118196 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
    filter

    如果所有的请求都需要过滤,urlPatterns="/*"

    如果用FilterRegistratronBran设置对应注册的类,类似于上面servlet,向里面 new 对象就可以

    官网

    http://felord.cn/_doc/_springboot/2.1.5.RELEASE/_book/pages/spring-boot-features.html#boot-features-embedded-container-servlets-filters-listeners

    28.4.1.1、将 Servlet、Filter 和 Listener 注册为 Spring Bean

    三、监听器

    listener是servlet规范定义的一种特殊类,用于监听servletContext,HttpSession和ServletRequest等域对象的创建和销毁事件。监听域对象的属性发生修改的事件,

    用于在事件发生前、发生后做一些必要的处理。可用于一下方面

    /*
    1、统计在线人数和在线用户
    2、系统启动时加载初始化信息
    3、统计网站访问量
    4、记录用户访问路径
    */

     新建listener目录,新建MyHttpSessionListener文件

    package xyz.kxq.listener;
    
    import javax.servlet.http.HttpSessionEvent;
    import javax.servlet.http.HttpSessionListener;
    
    public class MyHttpSessionListener implements HttpSessionListener {
        public static int online = 0;
    
        @Override
        public void sessionCreated(HttpSessionEvent se) {
            System.out.println("创建session");
            online++;
        }
    
        @Override
        public void sessionDestroyed(HttpSessionEvent se) {
            System.out.println("销毁session");
        }
    }

    需要创建session对象,代码中也没有注解,此时可以在SpringbootWebApplication文件加入Bean

    重新运行,会看到打印listener

    2021-10-22 10:26:49.921  INFO 151208 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
    2021-10-22 10:26:49.921  INFO 151208 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 747 ms
    listener

    添加控制层代码

    MyController

    package xyz.kxq.controller;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import xyz.kxq.listener.MyHttpSessionListener;
    
    @RestController
    public class MyController {
        @RequestMapping("hello")
        public String hello(){
            return "hello, springboot";
        }
    
        @RequestMapping("online")
        public String online(){
            return "当前在线人数: " + MyHttpSessionListener.online + "人";
        }
    }

    浏览器访问

     刷新一直是0;

    原因:

    监听器中创建session对象后才online++

    发送的请求没有任何session对象的请求,所以不会++

    在MyController

    package xyz.kxq.controller;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import xyz.kxq.listener.MyHttpSessionListener;
    
    import javax.servlet.http.HttpSession;
    
    @RestController
    public class MyController {
        @RequestMapping("hello")
        public String hello(HttpSession session){
            session.setAttribute("aa", "aa");
            return "hello, springboot";
        }
    
        @RequestMapping("online")
        public String online(){
            return "当前在线人数: " + MyHttpSessionListener.online + "人";
        }
    }

    在浏览器访问

     

  • 相关阅读:
    微信小程序 WePY 2 框架入门教程
    微信小程序 WePY 1.7.X 框架入门教程
    /deep/ 深度作用选择器作用及使用
    微信小程序 wx.getUserProfile 接口获取用户信息
    Wepy 微信小程序项目踩坑记
    计算机网络-第一章概述OSI参考模型
    如何安装pycocotools为文件?
    第三章 系统总线
    第二章 计算机的发展和展望
    第一章 计算机基础概论
  • 原文地址:https://www.cnblogs.com/kongxiangqun/p/15409708.html
Copyright © 2011-2022 走看看