• 【Spring】Spring MVC 拦截器的使用


    本文主要介绍 SpringMVC 中拦截器的使用和一个登录拦截的小案例


    1. 什么是拦截器

    Spring拦截器是一种基于 AOP 的技术,本质也是使用一种代理技术,它主要作用于接口请求中的控制器,也就是Controller。因此它可以用于对接口进行权限验证控制。

    2. 拦截器的实现

    拦截器的实现分为以下两个步骤:

    1. 创建自定义拦截器,实现 HandlerInterceptor 接口的 preHandle(执行具体方法之前的预处理) 方法。
    2. 将自定义拦截器加入 WebMvcConfigurer 的 addInterceptors 方法中。

    2.1 自定义拦截器

    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    // 只是定义了一个空白的拦截器类
    // 要让拦截器工作起来:
    // 1. 有个拦截器对象(自己new 或者 交给 Spring)
    // 2. 需要将对象注册,并且关联到某些 URL(哪些 URL 会应用拦截器),通过 WebConfigurator bean 来注册
    @Slf4j
    @Component
    public class MyInterceptor implements HandlerInterceptor {
        @Autowired
        public MyInterceptor() {
            log.info("MyInterceptor.MyInterceptor()");
        }
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            log.info("MyInterceptor.preHandle()");
    
    
            response.setCharacterEncoding("utf-8");
            response.setContentType("text/plain");
            response.getWriter().println("后续页面被拦截,不再执行");
    
            // 返回 true 代表后续继续执行,返回 false 代表后续不执行
            return false;
        }
    }
    
    • 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

    2.2 将自定义拦截器加入到配置中

    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    /*
     * Title:
     * Author: huang
     * Date: 2022/11/12 16:33
     */
    // 1. 必须是一个 Spring bean(否则没有机会调用)
    // 2. 必须实现了 WebMvcConfigurer 接口
    @Slf4j
    @Configuration
    public class InterceptConfig implements WebMvcConfigurer {
        private final MyInterceptor myInterceptor;
    
        @Autowired
        public InterceptConfig(MyInterceptor myInterceptor) {
            this.myInterceptor = myInterceptor;
        }
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            // 在这个方法中添加拦截器
    //        registry.addInterceptor(myInterceptor).addPathPatterns("/first/**");        // 为 first 下的所有 url 添加拦截器
            registry.addInterceptor(myInterceptor).addPathPatterns("/**")      // 拦截所有接口
                    .excludePathPatterns("/first/**");              // 排除接口
            log.info("WebConfig.addInterceptors()");
        }
    }
    
    • 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

    其中:

    • addPathPatterns:表示需要拦截的 URL,“**”表示拦截任意方法(也就是所有方法)。
    • excludePathPatterns:表示需要排除的 URL。

    说明:以上拦截规则可以拦截此项目中的使用 URL,包括静态文件(图片文件、JS 和 CSS 等文件)。

    3. 登录拦截器的实现

    登陆界面不拦截,其他界面拦截

    当登陆成功后,拦截的页面可正常访问

    说明:此拦截器可以实现访问页面判断用户是否登录,未登录直接重定向的功能

    3.1 自定义拦截器

    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Component;
    import org.springframework.web.servlet.HandlerInterceptor;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    
    @Slf4j
    @Component
    public class LoginInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            // 为了方便不创建实体类,直接用 Object
            Object currentUser = null;
            HttpSession session = request.getSession(false);
            if (session != null) {
                currentUser = session.getAttribute("currentUser");
            }
    
            if (currentUser == null) {
                // 说明用户未登录
                log.info("LoginInterceptor.preHandle: 用户未登录,重定向到 登录页(/login.html)");
                response.sendRedirect("/login.html");
                return false;
            }
    
            log.info("LoginInterceptor.preHandle: 用户登录了,继续后续操作。当前用户: {}", currentUser);
            return true;
        }
    }
    
    • 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

    3.2 将自定义拦截器加入配置中

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    @Configuration
    public class AppConfig implements WebMvcConfigurer {
        private final LoginInterceptor loginInterceptor;
    
        @Autowired
        public AppConfig(LoginInterceptor loginInterceptor) {
            this.loginInterceptor = loginInterceptor;
        }
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            // 注册拦截器
            registry.addInterceptor(loginInterceptor)
                    .addPathPatterns("/**")                 // 应用到所有 URL 上
                    .excludePathPatterns("/error")          // 只要有错误,都会到这
                    .excludePathPatterns("/login.do")
                    .excludePathPatterns("/login.html");    // 但是 /login.html 是例外
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    3.3 Controller 类

    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import javax.servlet.http.HttpSession;
    import java.util.LinkedHashMap;
    import java.util.Map;
    
    @Slf4j
    @Controller
    public class LoginDoController {
        @PostMapping("/login.do")
        public String login(String username, String password, HttpSession session) {
            // 为了方便不创建实体类,直接使用 Map 存放用户信息
            Map<String, String> user = new LinkedHashMap<>();
            user.put("username", username);
            user.put("password", password);
    
            session.setAttribute("currentUser", user);
    
            log.info("LoginDoController.login: 登录成功,重定向到首页(/)");
    
            return "redirect:/";
        }
    
        @GetMapping("/")
        @ResponseBody
        public String index() {
            return "首页";
        }
    
        @GetMapping("/hello")
        @ResponseBody
        public String hello() {
            return "其他页面";
        }
    }
    
    • 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
  • 相关阅读:
    linux usb驱动
    第十二章 哈希表与字符串哈希
    Java基础知识讲解-ArrayList类
    js详细讲解放大镜的实现
    vulhub中Apache Log4j Server 反序列化命令执行漏洞复现(CVE-2017-5645)
    XXE漏洞详解
    S7-PLCSIM Advanced V4.0安装步骤和使用入门
    关于vue.extend的理解应用
    c语言常见函数<sting.h>字符串处理函数
    华为ICT——云计算基础知识、计算类技术听课笔记
  • 原文地址:https://blog.csdn.net/m0_56975154/article/details/127856906