Spring-boot添加拦截器Interceptor进行认证验证

2022-08-12 11:27:16

在工作中实用SpringBoot已经有一段时间了,但却因为一次吃饭被师傅的一句话点醒,决定仔细认真的研究一下自己学习的东西,加深理解。找了本SpringBoot应用书籍,直接看书有的时候看的有点晕,就索性结合着博客学习,感觉博客里的兄弟搞的挺好的,通俗易懂。

我们为什么学习实用拦截器,拦截器可以实现什么功能,有什么优势呢,下面是我直接搜的一个兄弟的总结:

原文链接:原文链接

拦截器可以说相当于是个过滤器:就是把 不想要的或不想显示的内容给过滤掉。拦截器可以抽象出一部分代码可以用来完善原来的action。同时可以减轻代码冗余,提高重用率。
比如在登入一个页面时,如果要求用户密码、权限等的验证,就可以用自定义的拦截器进行密码验证和权限限制。对符合的登入者才跳转到正确页面。这样如果有新增权限的话,不用在action里修改任何代码,直接在interceptor里修改就行了。

1、好处:拦截器也可以让你将通用的代码模块化并作为可重用的类。Struts2中的很多特性都是由拦截器来完成的。
2、作用:可以构成拦截器栈,完成特定功能。比如日志记录、登录判断、权限检查等作用。

那么我们准备实用拦截器之前需要学习一点东西:

我们先学习两个东西,HandlerInterceptor 和  WebMvcConfigurerAdapter

第一种:实现HandlerInterceptor 接口,或者是继承实现了HandlerInterceptor 接口的类,例如HandlerInterceptorAdapter;
第二种:实现Spring的WebRequestInterceptor接口,或者是继承实现了WebRequestInterceptor的类。

HandlerInterceptor接口中定义了三个方法。

boolean preHandle() 该方法在处理请求之前进行调用,就是在执行Controller的任务之前。如果返回true就继续往下执行,返回false就放弃执行。

void postHandle()该方法将在请求处理之后,DispatcherServlet进行视图返回渲染之前进行调用,可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作,比如可以在这里将渲染的视图名称更改为其他视图名称。

void afterCompletion()该方法也是需要当前对应的Interceptor的preHandle方法的返回值为true时才会执行,该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行,也就是页面已经渲染完毕后调用此方法。用于进行资源清理。

public class SessionInterceptor implements HandlerInterceptor{
 
    /*在执行Controller的任务之前判断是否有Session信息
      如果有Session信息就往下执行,去调用Controller。
      如果没有Session就跳转到登录页面
    */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
 
        HttpSession session=request.getSession();
        if(session.getAttribute("User")!=null){
            return true;
        }
        String url = "/login.html";
        request.getRequestDispatcher(url).forward(request,response);
        return false;
    }
 
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        //controller 方法处理完毕后,调用此方法。
    }
 
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //页面渲染完毕后调用此方法,通常用来清除某些资源,类似Java语法的finally。
    }
}

WebMvcConfigurerAdapter:对Spring进行配置

@Configuration
public class WebSecurityConfig extends WebMvcConfigurerAdapter {
 
 
    @Bean
    public SessionInterceptor getSessionInterceptor() {
        return new SessionInterceptor();
    }
 
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        /*调用我们创建的SessionInterceptor。
        * addPathPatterns("/api/**)的意思是这个链接下的都要进入到SessionInterceptor里面去执行
        * excludePathPatterns("/login")的意思是login的url可以不用进入到SessionInterceptor中,直接
        * 放过执行。
        * 
        * 注意:如果像注释那样写是不可以的。这样等于是创建了多个Interceptor。而不是只有一个Interceptor
        * 所以这里有个大坑,搞了很久才发现问题。
        * 
        * */
        SessionInterceptor sessionInterceptor=new SessionInterceptor();
        registry.addInterceptor(sessionInterceptor).addPathPatterns("/api/**")
                .excludePathPatterns("/login","/verify");
//        registry.addInterceptor(sessionInterceptor).excludePathPatterns("/login");
//        registry.addInterceptor(sessionInterceptor).excludePathPatterns("/verify");
        super.addInterceptors(registry);
    }
}

WebMvcConfigurer

       WebMvcConfigurer是用来全局定制化SpringBoot的MVC特性。开发者通过实现WebMvcConfigurer接口来配置应用的MVC全局特性。

@Configuration
public class MvcConfigurer implements WebMvcConfigurer{
        //拦截器
        public void addInterceptors(InterceptorRegistry registry){
        
        }

        //跨域访问配置
        public void addCorsMappings(CorsRegistry registry){

        }

        //格式化
        public void addFormatters(FormatterRegistry registry){

        }

        
        //URI到视图的映射
        public void addViewControllers(ViewControllerRegistry registry){

        }

        //其他更多全局定制接口    
        
}

上面的代码就是实现这个功能的。来回顾一下需求和解决方法。

需求1、在登录前不管那个链接都跳转到Login页面。从WebMvcConfigurationAdapter里面看到,除了/login和verify其他的页面都要进入到Interceptor里面。

需求2、在登录验证成功里面添加Session就好了。

需求3、在Interceptor里面我们可以看到如果有Session就会通过,如果没有就会跳转到登录页面。

参考文档链接:https://blog.csdn.net/qq_24210767/article/details/78516616

  • 作者:coding_1994
  • 原文链接:https://blog.csdn.net/coding_1994/article/details/97514423
    更新时间:2022-08-12 11:27:16