zoukankan      html  css  js  c++  java
  • springboot_4 spring boot 使用servlet,filter,listener和interceptor

    上一篇我们学习了 spring boot 利用Controller响应数据与响应页面。 一般的Web开发使用 Controller 基本上可以完成大部分需求,但是有的时候我们还是会用到 Servlet、Filter、Listener 等等。

    在spring boot中添加自己的Servlet、Filter、Listener有两种方法

    • 代码注册: 通过ServletRegistrationBean、 FilterRegistrationBean 和ServletListenerRegistrationBean 获得控制。
    • 注解注册: 在SpringBootApplication 上使用@ServletComponentScan注解后,Servlet、Filter、Listener 可以直接通过 @WebServlet、@WebFilter、@WebListener 注解自动注册,无需其他代码。

    spring boot 中注册servlet

    代码注册

    • 创建Servlet类:AaServlet.java。
    public class AaServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("doGet");
            doPost(req, resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("doPost()");
            resp.setContentType("text/html");
            PrintWriter out = resp.getWriter();
            out.println("<h1>AaServlet</h1>");
        }
    }
    
    
    • 通过ServletRegistrationBean注册。
    //Project2Application.java
        @Bean
        public ServletRegistrationBean AaServletRegistration() {
            ServletRegistrationBean registration = new ServletRegistrationBean(new AaServlet());
            registration.addUrlMappings("/a");
            return registration;
        }
    
    • 运行测试。

    访问:http://localhost:8080/a

     
    测试

    注解注册

    • 创建Servlet类:BbServlet.java。
    @WebServlet(urlPatterns = "/b")
    public class BbServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("doGet");
            doPost(req, resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("doPost()");
            resp.setContentType("text/html");
            PrintWriter out = resp.getWriter();
            out.println("<h1>BbServlet</h1>");
    
        }
    }
    
    • 添加注解@ServletComponentScan。
    @ServletComponentScan
    @SpringBootApplication
    public class Project2Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Project2Application.class, args);
        }
    
        @Bean
        public ServletRegistrationBean AaServletRegistration() {
            ServletRegistrationBean registration = new ServletRegistrationBean(new AaServlet());
            registration.addUrlMappings("/a");
            return registration;
        }
    
    }
    
    • 运行测试。

    访问:http://localhost:8080/b

     
    测试

    filter 和 listener的注册和servlet一样。这里就不多说了。

    接下来说一下拦截器。

    自定义拦截器

    Spring提供了HandlerInterceptor(拦截器)。它的功能跟过滤器类似,但是提供更精细的的控制能力:在request被响应之前、request被响应之后、视图渲染之前以及request全部结束之后。我们不能通过拦截器修改request内容,但是可以通过抛出异常(或者返回false)来暂停request的执行。

    spring boot提供了一些拦截器,我们可以直接拿来使用,比如:

    • ConversionServiceExposingInterceptor
    • CorsInterceptor
    • LocaleChangeInterceptor
    • PathExposingHandlerInterceptor
    • ResourceUrlProviderExposingInterceptor
    • ThemeChangeInterceptor
    • UriTemplateVariablesHandlerInterceptor
    • UserRoleAuthorizationInterceptor

    我们也可以自己定义拦截器,定义拦截器的步骤大致分为:

    1、创建我们自己的拦截器类并实现 HandlerInterceptor 接口。
    2、创建一个Java类继承WebMvcConfigurerAdapter,并重写addInterceptors 方法。
    3、实例化我们自定义的拦截器,然后将对像手动添加到拦截器链中(在addInterceptors方法中添加)。

    我们来亲自试一下:

    • 创建我们自己的拦截器
    //MyInterceptor2
    public class MyInterceptor1 implements HandlerInterceptor {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {
            System.out.println("MyInterceptor1==========>在请求处理之前进行调用(Controller方法调用之前)");
    
            return true;// 只有返回true才会继续向下执行,返回false取消当前请求
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                               ModelAndView modelAndView) throws Exception {
            System.out.println("MyInterceptor1==========>请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)");
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
                throws Exception {
            System.out.println("MyInterceptor1==========>在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)");
        }
    
    }
    
    
    //MyInterceptor2
    public class MyInterceptor2 implements HandlerInterceptor {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {
            System.out.println("MyInterceptor2==========>在请求处理之前进行调用(Controller方法调用之前)");
    
            return true;// 只有返回true才会继续向下执行,返回false取消当前请求
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                               ModelAndView modelAndView) throws Exception {
            System.out.println("MyInterceptor2==========>请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)");
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
                throws Exception {
            System.out.println("MyInterceptor2==========>在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)");
        }
    
    }
    
    

    创建一个Java类继承WebMvcConfigurerAdapter,并重写addInterceptors 方法,添加拦截器。

    //MyWebAppConfigurer
    @Configuration
    public class MyWebAppConfigurer extends WebMvcConfigurerAdapter {
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            // 多个拦截器组成一个拦截器链
            // addPathPatterns 用于添加拦截规则
            // excludePathPatterns 用户排除拦截
            registry.addInterceptor(new MyInterceptor1()).addPathPatterns("/**");
            registry.addInterceptor(new MyInterceptor2()).addPathPatterns("/**");
            super.addInterceptors(registry);
        }
    
    }
    

    测试:运行项目,随便访问一个路径,比如http://localhost:8080/test

    浏览器会报错,不用管,看控制台。

     
    结果

    拦截器已经起作用了。

    值得注意的是:只有经过DispatcherServlet 的请求,才会走拦截器链,我们自定义的Servlet 请求是不会被拦截的,比如我们自定义的Servlet地址是不会被拦截器拦截的。

    但是过滤器不同。不管是属于哪个Servlet 只要复合过滤器的过滤规则,过滤器都会拦截。


    本篇文章就先介绍到这里,如果哪里讲的不明白,请及时与我联系。

    参考文章:Spring Boot 拦截器



    作者:cleverfan
    链接:https://www.jianshu.com/p/fba5c0fd09bb
    來源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    LinQ&EF任我行(一)LinQ to SQL (转)
    WPF数据模板和控件模板
    Sql优化
    SQL锁表语句
    js动态创建dom
    js实现等待n秒后按钮可用
    js关于事件冒泡
    工作流学习(个人总结)
    sql常用函数
    将Datatable序列化为Json对象返回到客户端
  • 原文地址:https://www.cnblogs.com/javaxiaoxin/p/8275348.html
Copyright © 2011-2022 走看看