SpringBoot 拦截器

社会主义新天地 提交于 2020-01-04 03:11:10

参考文章:

SpringBoot项目中,拦截器获取Post方法的请求body

Spring boot注解+拦截器实现以及拦截器无效的解决办法

spring boot入门(七) springboot的拦截器Interceptor。最完整、简单易懂、详细的spring boot教程。

在我们的项目中,有很多情景需要我们自己去实现拦截器,比如判断用户是否登录,限制用户请求的次数等等,在我们的Spring boot中我们可以通过注解+拦截器来实现我们的判断是否登录的注解。拦截器是来自MVC的拦截器,并不是boot自带的

1.创建自己的注解

spring boot中,我们可以创建我们的注解,下面我们来创建我们的IsLogin注解,代码如下:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

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

Target标签表示我们这个注解使用的范围,method表示这是个方法注解。Retention注解表示这个注解保留的时间,一共有三个选项:

  • SOURCE 注解会被编译器忽略
  • CLASS注解将会保留在Class文件中,但在运行的时候不会被VM保留,这是默认
  • RUNTIME保留至运行时,适合于想要用反射得到这个注解信息的情况

我们现在的IsLogin注解的参数是为了判断需要需要进行登录判断,默认为需要,我们在拦截器的时候需要去反射来得到isLogin()的值,所以我们采用RUNTIME来实现。

2.拦截器的实现

我们实现我们的LoginInterceptor,这个类需要继承HandlerInterceptorAdapter类,这个类里面有很多接口如下:

  • preHandle 在业务处理器请求之前调用,可以进行编码,安全控制,权限控制等等
  • postHandle在业务处理器请求执行完成后,生成视图渲染之前执行
  • afterCompletion在所有处理完成后执行
  • afterConcurrentHandlingStarted异步开始之前进行的处理

在咱们这里为了实现登录控制,我们只需要重写preHandle方法就行,代码如下:

import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

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

@Component
public class LoginInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
                            Object handler) throws Exception {
        if(handler instanceof HandlerMethod){
            HandlerMethod hm = (HandlerMethod)handler;
            IsLogin lm =  hm.getMethodAnnotation(IsLogin.class);
            System.out.println("lm is : " + lm);
            if(lm != null){
                //有lm注解,验证状态
                String name = request.getParameter("name");
                String password = request.getParameter("password");
                System.out.println("name is " + name);
                System.out.println("password is " + password);
                if(name != null && password != null && name != "" && password!="") {
                    return true;
                }else {
                    return false;
                }
            }else{
                return true;
            }
        }
        else{
            return false;
        }
    }
}

我们可以通过handle中的getMethodAnnotation来取得我们的IsLogin注解,然后访问注解的值来进行后续的判断

在我们这个demo中,我只是为了演示,所以判断用户请求传过来的参数是否有namepassword,如果没有的话是不允许进入这个页面,实际过程中可能需要从数据库或者缓存读取session然后判断用户是否登录。

3.注册拦截器

我们现在只是声明了我们的注解和拦截器,但是拦截器不会起作用,因为我们还需要注册我们的拦截器。
注意:新版本的Spring boot不再支持WebMvcConfigurerAdapter只支持WebMvcConfigurationSupport
刚开始我用WebMvcConfigurerAdapter导致拦截器无效,新版本总是想向下兼容导致很多不可用的包依然存在,这是Spring boot最大的坑…
具体代码如下:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;

@Configuration
public class LoginConfig extends WebMvcConfigurationSupport{
    @Autowired
    LoginInterceptor loginInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor).addPathPatterns("/xiaohuan");
        super.addInterceptors(registry);
    }
}

这样我们就完成了我们的登录控制,下面总结流程如下:

  1. 创建自己注解
  2. 创建自己的拦截器
  3. 将拦截器注册
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!