1.拦截的三种机制:
1.1 过滤器(Filter)
能拿到http请求,但是拿不到处理请求方法的信息。
1.2 拦截器(Interceptor)
既能拿到http请求信息,也能拿到处理请求方法的信息,但是拿不到方法的参数信息。
1.3 切片(Aspect)
能拿到方法的参数信息,但是拿不到http请求信息。
他们三个各有优缺点,需要根据自己的业务需求来选择最适合的拦截机制。
1.4 根据需求写拦截器:
**需求:**出于对接口的安全性的考虑,调用接口需要前端携带token值,以验证用户的合法性,如果用户合法,则允许用户调用接口,反之则禁止用户随意调用接口。
**前提条件:**这里的token值,是由用户登录时产生的随机码,当用户登录时,我们把生成token值和用户的信息,以key-value的形式存入redis,这样当前端调后端接口的时候,在请求头带上这个token值,我们就可以在后端写个拦截器,来校验用户的合法性了。
代码如下:
1.4.1 HandlerInterceptorAdapter
package com.cy.config;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//登录过滤拦截
//继承HandlerInterceptorAdapter适配器,重写预处理方法preHandlee
public class LoginInterceptor extends HandlerInterceptorAdapter {
/**
* 这个方法是在访问接口之前执行的,我们只需要在这里写验证登陆状态的业务逻辑,就可以在用户调用指定接口之前验证登陆状态了
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//判断session里面是否有用户,没有的话重定向到登录页面,给拦截掉
if (request.getSession().getAttribute("user")==null){
response.sendRedirect("/login");
return false;
}
/**
* 返回false:请求被拦截,返回
* 返回true:请求ok,可以继续执行,放行
*/
return true;
}
/**
* 请求controller之后,渲染视图之前
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) {
}
/**
* 请求controller之后,渲染视图之后
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) {
}
}
1.4.2WebMvcConfigurerAdapter
WebConfigurer :这个类中放开了swagger的访问,方便前后端联调
package com.cy.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
//指定拦截内容的配置类
@Configuration//表明是一个有效的配置类
public class WebConfig extends WebMvcConfigurerAdapter {
/**
* 这个方法用来注册拦截器,我们自己写好的拦截器需要通过这里添加注册才能生效
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// addPathPatterns("/**") //表示拦截所有的请求,
// excludePathPatterns("/login", "/register") //表示除了登陆与注册之外,因为登陆注册不需要登陆也可以访问
//(/**)==拦截所有请求
registry.addInterceptor(new LoginInterceptor())
//过滤的路径
//指定要拦截的路径,这里拦截"login"访问路径
.addPathPatterns("/login/**")
.excludePathPatterns("/login", "/register")
.excludePathPatterns("/login/index");
}
}