Spring boot 过滤器和拦截器

1、背景

咋一看过滤器和拦截器好像作用是一样的,但是如果我们仔细对这两个东西进行分析就可以得出结论。首先过滤器是对类级别进行阻挡。而拦截器是对方法级别进行阻挡。他们两个的应用角度也有所不同。过滤器的作用可以是使请求进入后台之前,我们做一些相应的处理,比如编码集转换,登录校验等等。而拦截器就比较灵活了,它可以拦下每个方法,这样他不仅仅是可以做登录校验,还可以做方法的日志打印,或者每一层之间切一个面出来进行提前处理类容。

2、过滤器使用方式

这里我主要介绍的是Spring boot项目中的使用方式,当然传统的web项目使用web.xml进行配置的过滤器大家应该已经非常清楚了。

首先在Spring boot项目中要使用过滤器,首先我们先写个正常的过滤器如下

package com.trs.zhjm.filter;

import javax.servlet.*;
import java.io.IOException;

public class testFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

    }

    @Override
    public void destroy() {

    }
}

至于这里面的方法是干嘛的,相信我不说大家都很清楚了。下面我们需要的是写配置类信息

package com.trs.zhjm.config;

import com.trs.zhjm.filter.testFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;

@Configuration
public class testConfig {

    @Bean
    public FilterRegistrationBean loginFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new testFilter());
        registration.addUrlPatterns("/*");
        registration.setName("checkLoginFilter");
        registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return registration;
    }
}

这样写完之后,我们就可以成功的对类进行过滤了。

下面我要说的是如何注入参数,在配置类里面可以再加一行类容。

  registration.addInitParameter("test", "注入参数");

那我们如何取呢?

  public FilterConfig config;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        config = filterConfig; 
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,         
   FilterChain filterChain) throws IOException, ServletException {

      String test= config.getInitParameter("test"); //获取注入类容
    }

按照这样的写法我们就可以直接使用了。这里我们要注意的是,配置类必须是要在Spring boot启动类扫描范围内的,不然无法生效。

3、拦截器的使用方式

一个拦截器类其实只需要实现HandlerInterceptor 这个接口就可以了

package com.trs.zhjm.controller;


import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;


@Component
public class PermissionsInterceptor implements HandlerInterceptor {

    /**
     * 进入方法之前拦截
     */
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws IOException {
        return true//代表通过拦截
        return false//代表不通过拦截
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}

当然我们也需要配置类来对它进行配置。

package com.trs.zhjm.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import java.nio.charset.Charset;

/**
 * 拦截器注入类
 */
@Configuration
@EnableWebMvc
public class PermissionsAdapter extends WebMvcConfigurerAdapter {

    @Autowired
    PermissionsInterceptor permissionsInterceptor;

    @Bean
    public HttpMessageConverter<String> responseBodyConverter() {
        StringHttpMessageConverter converter = new StringHttpMessageConverter(
                Charset.forName("gbk"));
        return converter;
    }

    /**
     * 注入拦截所有请求方法,放过login和exit
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(permissionsInterceptor).addPathPatterns("/**").excludePathPatterns("/login","/exit");

//代表拦截下/**的请求,放过 /login 和 /exit的请求
        super.addInterceptors(registry);
    }
}

同样拦截器配置类也是需要写在Spring boot 启动类下面的。

4、总结

相对来说拦截器比过滤器用起来方便一些,因为拦截器不需要考虑请求完成之后,又回到拦截器的问题,而过滤器当我们请求执行完成之后,还会回到过滤器,如果判断没有写完整会出现一只在过滤器里面跑的问题。当然还有就是过滤器是基于serlet才能够使用的,而拦截器只要是用Spring管理的项目就可以使用啦。

面向切面编程其实是对另外一种思维方式的改变,如果对全体方面考虑不够周全其实能不使用我自己一般都不会考虑用这样的方法的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章