了解拦截器

发布于:2025-04-05 ⋅ 阅读:(17) ⋅ 点赞:(0)

目录

什么是拦截器

拦截器的基本使用

拦截器的使用步骤

拦截器路径设置

拦截器执行流程


 

一、什么是拦截器

拦截器是Spring框架提供的核心功能之一,主要用来拦截用户的请求,在指定方法前后,根据业务需要执行预先设定的代码。

开发人员可以提前定义一些逻辑,在用户的请求响应前后执行,比如通过拦截器来拦截前端发来的请求,要求用户强制进行登录,判断Session中是否有登录用户的信息,如果有就可以放行,如果没有就拦截。

 举个例子:比如我们去银行办理业务,在办理业务前后,就可以加一些拦截操作。

在办理业务之前,先取号,如果带身份证了就取号成功;业务办理结束,给业务办理人员的服务进行评价,这些就是“拦截器”做的工作。


二、拦截器的基本使用

在使用拦截器之前,先创建一些类:

  • User类:
@Data
public class User {
    private String username;
    private String password;
}
  • UserController类:
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    GetUser getUser;

    @RequestMapping("/login")
    public String login(String username, String password, HttpServletRequest request) {
        User user = getUser.getUser(username, password);
       if (user == null) {
           return "账号或密码错误";
       }
        request.getSession().setAttribute("user", user);
        return "账号密码正确,登录成功";
    }

    @RequestMapping("/enter")
    public String Enter(){
        return "进入页面";
    }
}
  •  GetUser类
@Service
public class GetUser {
    public User getUser(String username, String password) {
        if (username == null || password == null) {
            return null;
        }
        if (!"zhangsan".equals(username) ||!"123".equals(password)) {
            return null;
        }
        User user = new User();
        user.setUsername("zhangsan");
        user.setPassword("123");
        return  user;
    }
}

拦截器的使用步骤

  1. 定义拦截器
  2. 注册配置拦截器

1.自定义拦截器:实现HandlerInterceptor接口,并重写其所有方法:

//自定义拦截器,实现HandlerInterceptor接口并重写其所有方法
@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response, Object handler) throws Exception {
      log.info("拦截开始");
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute( "user");
        if (user == null) {
            log.info("被拦截");
            return false;
        }else {
            log.info("不拦截,放行");
            return true;
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response,
                           Object handler, ModelAndView modelAndView) throws Exception {
        log.info("enter方法执行后");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("LoginInterceptor 视图渲染完毕后执⾏,最后执⾏");
    }
}
  • preHandle()方法:目标方法执行前执行。返回true时,表示目标方法未被拦截,放行,继续执行后续操作;返回false时,拦截目标方法,中断后续操作。
  • postHandle()方法:目标方法后执行。
  • afterCompletion()方法:视图渲染完毕后执行,最后执行(了解)。

2.注册拦截器:实现WebMvcConfigurer接口,并重写addInterceptors方法。

@Configuration
public class WebConfig implements WebMvcConfigurer {
    //自定义拦截器对象
    @Autowired
    private LoginInterceptor loginInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor)
                .addPathPatterns("/**")
                //排除拦截的页面,登录页
                .excludePathPatterns("/user/login");
    }
}

补充:上面的拦截路径中,addPathPatterns方法表示拦截的路径,excludePathPatterns表示为排除要拦截的路径,排除了/user/login这个路径了。

完毕后启动服务,试试访问请求,观察后端日志。

可以看到,enter路径的被拦截了,因为没有进行登录操作。

  • 然后再尝试着先访问login页面进行登录然后再进行访问enter页面。

然后再访问URL:http://127.0.0.1:8080/user/enter,观察日志。

 可以看到,进行登录之后,保存了登录信息,再进行访问enter页面时就不会被拦截了。

拦截器路径设置

拦截器中除了可以设置 /** 拦截所有资源外,还有一些常见拦截路径设置:

拦截路径 含义 举例
/* 一级路径 能匹配/user,/book,/login,不能匹配/user/login
/** 任意级路径 能匹配/user,/user/login,/user/reg
/book/* /book下的一级路径 能匹配/book/addBook,不能匹配/book/addBook/1,/book
/book/** /book下的任意级路径 能匹配/book,/book/addBook,/book/addBook/2,不能匹配/user/login

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

拦截器执行流程

正常的调用顺序:

 有了拦截器之后,会在调用Controller之前进行相应的业务处理,执行的流程如下图:

 1.添加拦截器后,执行Controller的方法之前,请求会先被拦截器拦截住,执行preHandle()方法,这个方法需要返回一个布尔类型的值,如果返回true,就表示放行本次操作,继续访问controller中的方法;如果返回false,则不会放行(controller中的方法也不会执行)。

2.controller当中的方法执行完毕后,再回来执行postHandle()这个方法以及afterCompletion()方法,执行完毕之后,最终给浏览器相应数据。