第八节 SpringBoot使用过滤器与拦截器

一、过滤器Filter

        创建过滤器的方法很简单,也传统的WEB项目一样,实现 Filter接口即可

package com.zhoutianyu.learnspringboot.filter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class MyFilter implements Filter {

    private static final Logger LOGGER = LoggerFactory.getLogger(MyFilter.class);

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;

        LOGGER.info("自定义过滤器工作,当前请求URL:{}", httpServletRequest.getRequestURL());
        LOGGER.info("自定义过滤器工作,当前请求URI:{}", httpServletRequest.getRequestURI());

        //放行
        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }
}

        老式的做法就是在web.xml中配置这个过滤器。在SpringBoot中的步骤

        (1)实现 Filter 接口,实现其中的 doFilter() 方法;

        (2)添加 @Configuration 注解,将自定义 Filter 加入过滤链。

          SpringBoot的优势几乎就在于,所有的配置均有Java来控制。比如添加匹配过滤,addUrlPattern。

          order是拦截顺序,数值越小,拦截优先级越高。

          下面的代码是将自定义Filter加入到过滤链。

package com.zhoutianyu.learnspringboot.config;

import com.zhoutianyu.learnspringboot.filter.MyFilter;
import com.zhoutianyu.learnspringboot.filter.MyFilter2;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean myFilter() {
        FilterRegistrationBean<MyFilter> filterContainer = new FilterRegistrationBean<>();
        filterContainer.setFilter(new MyFilter());
        //filter pattern
        filterContainer.addUrlPatterns("/*");
        //filter name
        filterContainer.setName("MyFilter");
        //filter order
        filterContainer.setOrder(1);
        return filterContainer;
    }

}

        启动项目,访问项目根目录:http://localhost:8081/study/springboot/

        后台控制台打印,说明当前过滤器MyFilter正常工作。

        创建一个MyFilter2,用于拦截URL中的参数。并将这个MyFilter2加入拦截器链。

package com.zhoutianyu.learnspringboot.filter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class MyFilter2 implements Filter {

    private static final Logger LOGGER = LoggerFactory.getLogger(MyFilter2.class);

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;

        String param = httpServletRequest.getParameter("param");
        LOGGER.error("自定义过滤器2工作,参数param是:{}", param);

        //放行
        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }
}

        把MyFilter2加入到过滤器链中。

        将MyFilter2过滤器的过滤顺序order设置为2。预期MyFilter2的拦截顺序低于MyFilter。

    @Bean
    public FilterRegistrationBean myFilter2() {
        FilterRegistrationBean<MyFilter2> filterContainer = new FilterRegistrationBean<>();
        filterContainer.setFilter(new MyFilter2());
        //filter pattern
        filterContainer.addUrlPatterns("/*");
        //filter name
        filterContainer.setName("MyFilter2");
        //filter order
        filterContainer.setOrder(2);
        return filterContainer;
    }

        重启项目,重新访问项目根目录:http://localhost:8081/study/springboot/?param=study_filter

        根据实际后台打印结果,说明MyFilter2的拦截顺序低于MyFilter。

二、拦截器Interceptor

        过滤器与拦截器,这两个词汇其实本质上是一样的。都是对URL进行处理与拦截。

        Filter侧重点是要不要让某个请求进入我们系统。

        Interceptor侧重点是请求进入我们的系统后,进行预处理、后处理。

        编写拦截器最常见也是最简单的方法是,继承HandlerInterceptorAdapter。

  (1)编写一个拦截器并声明为一个Bean

package com.zhoutianyu.learnspringboot.interceptor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
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 MyInterceptor extends HandlerInterceptorAdapter {

    private static final Logger LOGGER = LoggerFactory.getLogger(MyInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        LOGGER.info("资源预处理");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
        LOGGER.info("资源后处理");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
        LOGGER.info("请求完成,清理资源");
    }

}

(2)将拦截器添加到WEB配置中。

package com.zhoutianyu.learnspringboot.config;

import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.zhoutianyu.learnspringboot.interceptor.MyInterceptor;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.annotation.Resource;

@Configuration
public class CustomWebConfigure implements WebMvcConfigurer {

    @Resource
    private MyInterceptor interceptor;


    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(interceptor).addPathPatterns("/**")
               .excludePathPatterns("/static/**");
    }
}

        测试:

        访问:http://localhost:8081/study/springboot/param/test2?param=interceptor

        这里引用了上一节的/param/test2接口。可以下载我的源码尝试访问。

        下面的返回结果,显示了一次完整的HTTP请求后台过滤器与拦截器的执行流程。

         首先是两个过滤器Filter进行工作。HTTP请求在通过了过滤器后,开始对我们的资源进行访问。

         这个时候,拦截器Interceptor就开始工作。

         首先是访问前的:"资源预处理",然后在返回资源响应后的后处理:"资源后处理",最后请求完成后:"请求完成,清理资源"。

          以后的通过ThreadLocal进行分页的处理,将会用到拦截器Interceptor相关技术。

三、源码下载

        本章节项目源码:点我下载源代码

        目录贴:跟着大宇学SpringBoot-------目录帖

如果本文对你有帮助,不妨请我喝瓶可乐吧!

你的打赏是对我最好的支持!

                    

posted @ 2022-07-17 12:14  小大宇  阅读(486)  评论(0编辑  收藏  举报