SpringBoot使用拦截器

马里奥 2020年09月29日 20次浏览

前言

在面向对象编程过程中,我们很容易通过继承、多态来解决纵向扩展,在Spring项目中,使用拦截器可以实现横向扩展。

拦截器配置

通过拦截器实现登录态验证,判断是否满足放行条件:

@Component
public class AuthorityInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisService redisService = null;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        //利用反射查看被调用方法是否要求登录
        //请求controller中的方法名
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Access access = handlerMethod.getMethodAnnotation(Access.class);
        if (access == null) return true;
        boolean requireLogin = access.requireLogin();
        if (!requireLogin) return true;
        boolean login = checkLogin(request);
        if (login) return true;
        else {
            try {
                response.sendRedirect("/login");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return false;
    }

    //校验登录态
    private boolean checkLogin(HttpServletRequest request) {
        String token = CookieUtil.readLoginToken(request);
        if (token == null) return false;
        boolean exist = redisService.exists(UserKeyPrefix.TOKEN, token);
        if (!exist) return false;
        return true;
    }
}

这里需要实现HandlerInterceptor,实现其中的preHandle方法,对要求登录态的地址映射做校验。

控制器中的方法加上@Access注解表示该接口要求登录态,如:

@RequestMapping(value = "/index", method = RequestMethod.GET)
@Access
public String index() {
	return "/index";
}

来看看@Access:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Access {
    boolean requireLogin() default true;
}

注册拦截器

接下来我们需要注册拦截器,注册完成这个拦截器才会工作,建立配置类:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private AuthorityInterceptor authorityInterceptor = null;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        InterceptorRegistration registration = registry.addInterceptor(authorityInterceptor);
        registration.addPathPatterns("/**");			    //拦截所有路径
        registration.excludePathPatterns(                           //添加不拦截路径
                "/login",                                           //登录
                "/register",                                        //注册
                "/**/*.html",                                       //html静态资源
                "/**/*.js",                                         //js静态资源
                "/**/*.css",                                        //css静态资源
                "/**/*.woff",
                "/**/*.ttf"
        );
    }
}

preHandle若返回真,则继续执行控制器方法,否则停止执行,当然也可以像AuthorityInterceptor那样,登录态校验失败跳转到登录页面。

参考

基于SpringBoot + Redis + Mybatis商品秒杀系统
Spring Boot实战:拦截器与过滤器详解与使用!!!
Springboot 拦截器配置(登录拦截)