springboot之拦截器

springboot之拦截器

当我们的系统存在页面需要登录才能使用时,可以使用拦截器去做登录判断。


登录和主页

为了模拟使用场景,我写了一个包含登录和主页的Controller,如下

@Controller
public class MyController {
    // 登录页
    @GetMapping("/login")
    public String loginPage() {
        return "login";
    }

    // 登录
    @PostMapping("/login")
    public String login(HttpSession session, @RequestParam String username, @RequestParam String password) {
        if (StringUtils.hasLength(username) && StringUtils.hasLength(password)) {
            // 若输入了用户名和密码,则向session中添加用户名
            session.setAttribute("user", username);
            // 重定向到首页
            return "redirect:/";
        } else {
            // 否则返回登录页
            return "login";
        }
    }

    // 首页
    @GetMapping("/")
    public String indexPage() {
        return "index";
    }
}

创建拦截器

拦截器需要实现接口HandlerInterceptor,其包含三个方法,分别是

  • preHandle:视图解析器执行前执行,当返回false时不执行视图解析器
  • postHandle:视图解析器执行后执行
  • afterCompletion:页面渲染完成后执行,当preHandletrue时,无论后面视图解析器是否真正执行,都会执行afterCompletion

登录的拦截器如下

public class LoginInterceptor implements HandlerInterceptor {

    // 视图解析器执行前
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
        throws Exception {
        HttpSession session = request.getSession();
        String user = (String) session.getAttribute("user");// 获取session中的用户
        if (StringUtils.hasLength(user)) {// 如果用户存在,则放行
            return true;// 放行
        }
        // 若没有登录,则拦截,重定向到登录页
        response.sendRedirect("/login");
        return false;// 拦截
    }

    // 视图解析器执行后
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
        ModelAndView modelAndView) throws Exception {

    }

    // 页面渲染完成后
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
        throws Exception {

    }
}

注册拦截器

我们需要写一个配置类来将我们的拦截器加入到springboot中,并指定拦截器生效的范围,因为配置类要定制SpringMVC的功能,所以需要实现WebMvcConfigurer接口,重写addInterceptors方法,如下

@Configuration
public class MyConfigurer implements WebMvcConfigurer {

    // 添加自定义拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
            .addPathPatterns("/**")// 对所有请求进行拦截,包括静态资源访问
            .excludePathPatterns("/login"); // 排除登录页
    }
}
  • /**:表示当前路径及其子路径下的所有路径
  • /*:表示当前路径下的所有路径,不包括子路径

注意,当拦截器拦截/**路径时,会拦截静态资源的访问,所以需要将静态资源的访问路径加入到排除路径中。我们可以设置静态资源访问前缀,再将该前缀加入到排除路径中即可。这里我没用到静态资源,所以没加。


拦截器执行过程

  1. 根据当前请求,找到 HandlerExecutionChain【包括可以处理请求的handler以及handler的所有拦截器】
  2. 先来顺序执行所有拦截器的 preHandle方法
    1. 如果当前拦截器 preHandle返回为true,则执行下一个拦截器的 preHandle
    2. 如果当前拦截器返回为 false,直接倒序执行所有已经执行了的拦截器的 afterCompletion
  3. 如果任何一个拦截器返回 false,直接跳出不执行目标方法
  4. 所有拦截器都返回True,执行目标方法
  5. 倒序执行所有拦截器的postHandle方法
  6. 前面的步骤有任何异常都会直接倒序触发 afterCompletion
  7. 页面成功渲染完成以后,也会倒序触发 afterCompletion

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值