• Spring Boot 拦截器的使用


    一、使用场景

    比如对特定的URL检查用户是否登录,打印处理用户请求耗时的时间等,可以用拦截器来实现。


    二、拦截器使用

    定义拦截器,需要实现 HandlerInterceptor 接口,接口中有3个方法

    • preHandle:在DispatcherServlet处理请求执行之前被调用
    • postHandle:在DispatcherServlet处理请求执行完成后,生成视图之前被调用(还未渲染页面)
    • afterCompletion:在DispatcherServlet处理请求执行完成后,且已生成视图被调用,可以用于清除资源(已渲染了页面)

    )2.1 创建自定义拦截器 MyInterceptor  类

    @Slf4j
    public class MyInterceptor implements HandlerInterceptor {
    
        /**
         * 定义拦截器:需要实现 HandlerInterceptor 接口
         *
         * HandlerInterceptor接口中有3个方法
         * 1.preHandle:在业务处理器处理请求之前被调用
         * 2.postHandle:在业务处理器处理请求执行完成后,生成视图之前执行(还未渲染页面))
         * 3.afterCompletion:在DispatcherServlet完全处理完请求后被调用,可用于清理资源等。返回处理(已经渲染了页面)
         */
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            String methodName = method.getName();
            log.info("===拦截到了方法:{},在该方法执行之前执行===", methodName);
    
            // 判断用户有没有登陆,一般登陆后的用户都有一个对应的token
            String token = request.getParameter("token");
            if (StringUtils.isEmpty(token)) {
                log.info("用户没有登陆,没有执行权限......请登陆");
                return false;
            }
    
            // 通过方法,可以获取该方法上的自定义注解,然后通过注解来判断该方法是否要被拦截
            // @UnInterceptor 自定义注解,不被拦截
            UnInterceptor unInterceptor = method.getAnnotation(UnInterceptor.class);
            if (null == unInterceptor) {
                return false;
            }
    
            return true;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            log.info("执行完方法之后进行(Controller方法调用之后),但是此时还没有进行视图渲染");
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            log.info("整个请求都处理完毕,DispatcherServlet也渲染了对应的视图,此时可以做一些清理的工作等等");
        }
    }

    )2.2 创建拦截器配置类,实现 WebMvcConfigurer 接口,对所有请求由 MyInterceptor 类进行拦截

    @Configuration
    public class MyInterceptorConfig implements WebMvcConfigurer {
    
        /**
         * 解决静态资源被拦截问题
         *
         * @param registry
         */
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            // 实现WebMvcConfigurer不会导致静态资源被拦截
            registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
        }
    }

    )2.3 创建controller类,接收请求

    @Controller
    @RequestMapping("/interceptor")
    public class InterceptorController {
    
        @GetMapping("/test")
        public String test() {
            return "hello";
        }
    
        @UnInterceptor
        @GetMapping("/test1")
        @ResponseBody
        public String test1() {
            return "不被拦截";
        }
    }

    )2.4 创建 hello.html 页面,用于页面返回渲染


    三、测试

    )3.1 对于 token 校验测试。在 MyInterceptor 类中的 preHandle 方法中注释 @UnInterceptor 校验的代码,

     访问 localhost:8080/interceptor/test 时,会被拦截,由于没有带token值,执行 preHandle 方法时返回false,不会继续往下执行

     通过 postman 表单请求设置 token 值,再次请求

    测试结果如下,可以看到 MyInterceptor 类中,三个方法都已执行,且返回了 hello.html 中的页面

    )3.2 对于自定义注解校验测试。在 MyInterceptor 类中的 preHandle 方法中注释token校验的代码,放开 @UnInterceptor 的校验代码,

    访问 localhost:8080/interceptor/test1 可以看到 MyInterceptor 类中,三个方法都已执行

  • 相关阅读:
    前端三剑客之css 后续
    前端三剑客之css
    优酷项目遇到的知识点回顾
    MySQL 里 视图,触发器,事物,存储过程,内置函数,流程控制,索引
    mysql的用户管理
    数据库管理工具 navicat 相关的练习
    MySQL 单表查询,多表查询
    MySQL 外键 表与表的关系 多对一,多对多,一对一,表的修改 与 复制
    ORM基础
    Django路由系统
  • 原文地址:https://www.cnblogs.com/lwcode6/p/13450712.html
Copyright © 2020-2023  润新知