• SpringBoot-拦截器


    SpringBoot-拦截器

    1.基本介绍

    1. 在 Spring Boot 项目中, 拦截器是开发中常用手段,要来做登陆验证、性能检查、日志记录等。

    2. 基本步骤:

    √ 编写一个拦截器实现 HandlerInterceptor 接口

    √ 拦截器注册到配置类中(实现 WebMvcConfigurer 的 addInterceptors)

    √ 指定拦截规则

    image-20220807182359263

    2.拦截器应用实例

    1.需求: 使用拦截器防止用户非法登录, 如图 - 使用拦截器就不需要在每个方法验证了

    ● 浏览器输入 : http://localhost:8080/manage.html , 如果用户没有登录,则返回登录界面.

    image-20220807183609295

    2.代码实现

    1.创建src\main\java\com\llp\springboot\interceptor\LoginInterceptor.java

    @Slf4j
    @Component
    public class LoginInterceptor implements HandlerInterceptor {
    
        /**
         * 目标方法执行之前执行
         * @param request
         * @param response
         * @param handler
         * @return
         * @throws Exception
         */
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            //看看requestURI 和 requestURL的区别
            String requestURI = request.getRequestURI();
            String requestURL = request.getRequestURL().toString();
            //URI=/manage.html
            log.info("preHandle拦截到的请求的URI={}", requestURI);
            //URL=http://localhost:8080/manage.html
            log.info("preHandle拦截到的请求的URL={}", requestURL);
    
            Object admin = request.getSession().getAttribute("admin");
            if (admin != null) {
                return true;
            }
    
            //拦截, 重新返回到登录页面
            //adminLogin.html 去除msg的方式是从request域获取
            request.setAttribute("msg", "您尚未登录,请登录");
            request.getRequestDispatcher("/").forward(request, response);
            return false;
        }
    
        /**
         * 在目标方法被执行后执行. 可以在方法中访问到目标方法返回的 ModelAndView 对象
         * 若 preHandle 返回 true, 则 afterCompletion 方法 在渲染视图之后被执行.
         * 若 preHandle 返回 false, 则 afterCompletion 方法不会被调用
         * @param request
         * @param response
         * @param handler
         * @param modelAndView
         * @throws Exception
         */
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            log.info("postHandle 执行了。。。");
        }
    
        /**
         * 在渲染视图之后被执行.
         * @param request
         * @param response
         * @param handler
         * @param ex
         * @throws Exception
         */
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            log.info("afterCompletion 执行了。。。");
        }
    }
    
    • 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
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    2.创建src\main\java\com\llp\springboot\config\WebConfig.java对我们定义的拦截器进行注册拦截路径配置

    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            /**
             * 1.拦截器会先拦截controller的路径映射
             * 2.如果找不到则去静态资源下查找
             * 3.这里配置/**会拦截所有的请求,包括静态资源
             * 4.这里不拦截静态资源,为什么直接写成 "/images/**","/css/**" ?
             * 5.在SpringBoot中引入了spring-boot-starter-web 依赖,每个starter都会对于的自动装配
             * 6.在WebProperties中配置了类路径映射,因此可以直接省略/static/
             * private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
             *              "classpath:/resources/", "classpath:/static/", "classpath:/public/" };
             *
             */
            registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/","/login","/images/**","/css/**");
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    3.修改src\main\java\com\llp\springboot\controller\AdminController.java

    @Controller
    public class AdminController {
    
        @PostMapping("/login")
        public String login(Admin admin, HttpSession session, Model model) {
            if (StringUtils.hasText(admin.getUsername()) && "666".equals(admin.getPassword())) {
                //1.这里使用重定向,不适用请求转发,防止刷新页面表单重复提交
                //2./manage.html /会被解析成ip:port ,而manage.html是指定浏览器下一次请求访问的路径
                //3.重定向会发起get请求
                System.out.println(admin);
                session.setAttribute("admin", admin);
                return "redirect:/manage.html";
            } else {
                model.addAttribute("msg", "密码错误");
                return "adminLogin";
            }
        }
    
        @GetMapping("manage.html")
        public String manage(Model model, HttpSession session) {
    
                //可以这里集合-模拟用户数据, 放入到request域中,并显示
                ArrayList<User> users = new ArrayList<>();
                users.add(new User(1, "关羽~", "666666", 20, "gy@sohu.com"));
                users.add(new User(2, "张飞", "666666", 30, "zf@sohu.com"));
                users.add(new User(3, "赵云", "666666", 22, "zy@sohu.com"));
                users.add(new User(4, "马超", "666666", 28, "mc@sohu.com"));
                users.add(new User(5, "黄忠", "666666", 50, "hz@sohu.com"));
    
                //将数据放入到request域
                model.addAttribute("users", users);
    
                return "manage";
        }
    
    }
    
    • 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

    测试效果

    image-20220807183609295

    image-20220807185059400

    3.注意事项和细节

    1、URI 和 URL 的区别

    ​ URI = Universal Resource Identifier URL = Universal Resource Locator Identifier:标识符,

    ​ Locator:定位器 从字面上来看, URI 可以唯一标识一个资源, URL 可以 提供找到该资源的路径

    2、注册拦截器, 依然可以使用如下方式

    @Configuration
    public class WebConfig  {
    
        @Bean
        public WebMvcConfigurer webMvcConfigurer(){
            return new WebMvcConfigurer() {
                @Override
                public void addInterceptors(InterceptorRegistry registry) {
                    registry.addInterceptor(new LocaleChangeInterceptor())
                            .addPathPatterns("/**")
                            .excludePathPatterns("/","/login","/images/**","/css/**");
                }
            };
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
  • 相关阅读:
    【Linux】线程安全
    flutter系列之:flutter中常用的GridView layout详解
    WPF Prism框架搭建
    Java学习笔记(十四):String类
    Windows系统部署WebDAV服务结合内网穿透实现公网访问,轻松共享文件与资源
    产品代码都给你看了,可别再说不会DDD(六):聚合根与资源库
    【无人机路径规划】基于改进差分算法实现三维多无人机协同航迹规划附matlab代码
    驱动开发:内核监控Register注册表回调
    IMU+摄像头实现无标记运动捕捉
    基于SSM的疫情期间高校师生外出请假管理系统设计与实现
  • 原文地址:https://blog.csdn.net/qq_44981526/article/details/126213275