springBoot-------实现简单的拦截器

引言

在做后台管理系统时,要进入功能页需要判断一下用户是否登录,此时就体现出拦截器的作用了。

springBoot实现拦截器主要有三步:

  • 编写一个拦截器实现HandlerInterceptor接口,并实现preHandle拦截方法
  • 将拦截器注册到容器中(实现WebMvcConfigurer接口,并重写addInterceptors方法)
  • 编写拦截器规则【注意静态资源的拦截】

内容

编写一个web项目,访问/main路径时候,要判断是否登录,登录即可进入,否则跳回登录页面并给予提示。

拦截器:

package com.xiao.boot.interceptor;


import com.xiao.boot.bean.User.User;
import org.omg.PortableInterceptor.Interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

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 {
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("user");
        if (user == null){
            // 拦截
            request.setAttribute("msg","请先登录");
            request.getRequestDispatcher("/").forward(request,response);
            return false;
        }
        // 放行
        return true;
    }


    /**
     * 目标方法执行后
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

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

    }
}

配置拦截器。注意要将静态资源放行

package com.xiao.boot.config;

import com.xiao.boot.interceptor.LoginInterceptor;
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 AdminWebConfig implements WebMvcConfigurer {

    // 添加拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**")   //拦截所有,包括静态资源
                .excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**");  //放行
    }
}

登录的controller

package com.xiao.boot.controller;

import com.sun.org.apache.xpath.internal.operations.Mod;
import com.xiao.boot.bean.User.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.thymeleaf.util.StringUtils;

import javax.servlet.http.HttpSession;

@Controller
public class UserController {

    @GetMapping(value = {"/","/login"})
    public String loginPage(){
        return "login";
    }

    @PostMapping(value = "/login")
    public String main(User user, HttpSession session,Model model){

        if (!StringUtils.isEmpty(user.getUserName()) && user.getPassword().equals("123456")){
            session.setAttribute("user",user);
            return "redirect:/main.html";
        }else {
            model.addAttribute("msg","账号或密码错误");
            return "login";
        }


    }

    @GetMapping(value = "/main.html")
    public String mainPage(HttpSession session, Model model){
        return "main";
    }
}

结果

首先进入登录页面

直接访问main,被拦截,并且提示登录

输入账号和密码进行登录

拦截器原理

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

posted @ 2021-01-07 11:56  littlemelon  阅读(1720)  评论(0编辑  收藏  举报