springboot 之 自定义过滤器

过滤器的流程

Filter对用户请求进行预处理,接着将请求交给Servlet进行预处理并生成响应,最后Filter再对服务器响应进行后处理。

缺点

不知道当前请求属于那个controller

实现方式

Filter是servlet的接口类,需要实现三个接口。

我使用的环境:

win 7 64bit

IDEA 2018 1.3

实现方式一:

1)使用Servlet3.0的注解进行配置
2)启动类里面增加 @ServletComponentScan,进行扫描
3)新建一个Filter类,implements Filter,并实现对应的接口
4) @WebFilter 标记一个类为filter,被spring进行扫描 
	urlPatterns:拦截规则,支持正则
6)控制chain.doFilter的方法的调用,来实现是否通过放行
   不放行。	场景:权限控制、用户登录(非前端后端分离场景)等

代码:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

@SpringBootApplication
//扫描servlet过滤器
@ServletComponentScan
public class MydefinationApplication {

	public static void main(String[] args) {
		SpringApplication.run(MydefinationApplication.class, args);
	}

}
package com.example.mydefination.filter;

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

//指定过滤规则,可以使用正则表达式。filtername指定过滤器名字
@WebFilter(urlPatterns = "/api/v1/*", filterName = "version1 filter")
public class MyFilter  implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("init Filter1");
    }


    /**
     *     使用Filter完整的流程是:
     *     Filter对用户请求进行预处理,接着将请求交给Servlet进行预处理并生成响应,
     *     最后Filter再对服务器响应进行后处理。
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("doFilter version1");

        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;

        //一些其他判断
        if ("user".equals(req.getParameter("username"))){
            filterChain.doFilter(req, resp);
        }else{
            resp.sendRedirect("/index.html");
            return;
        }

    }

    @Override
    public void destroy() {
        System.out.println("destroy Filter1");
    }
}

实现方式二

自己写配置类,注册自定义的过滤器

代码:

注册类:

import com.example.mydefination.filter.MyFilterTwo;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.List;

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean twoFilter(){
        MyFilterTwo myFilterTwo = new MyFilterTwo();
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(myFilterTwo);
        List<String> urls = new ArrayList<>();
        urls.add("/api/v2/*");
        filterRegistrationBean.setUrlPatterns(urls);

        return filterRegistrationBean;
    }
}

自定义过滤器:

import org.springframework.stereotype.Component;

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

@Component
public class MyFilterTwo implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("init Filter2");
    }


    /**
     *     使用Filter完整的流程是:
     *     Filter对用户请求进行预处理,接着将请求交给Servlet进行预处理并生成响应,
     *     最后Filter再对服务器响应进行后处理。
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("doFilter version2");

        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;

        //一些其他判断
        if ("user".equals(req.getParameter("username"))){
            System.out.println("url:" + req.getRequestURL());
            filterChain.doFilter(req, resp);
        }else{
            resp.sendRedirect("/index.html");
            return;
        }

    }

    @Override
    public void destroy() {
        System.out.println("destroy Filter2");
    }
}

上面两个测试Controller代码:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

    /**
     * 测试URL
     * http://localhost:8080/api/v1/hello1?username=user
     * @return
     */
    @GetMapping(value = "api/v1/hello1")
    public String hello1(){
        System.out.println("进入hello1 11111111111");
        return "hello1";
    }

    /**
     * 测试URL
     * http://localhost:8080/api/v2/hello2?username=user
     * @return
     */
    @GetMapping(value = "api/v2/hello2")
    public String hello2(){
        System.out.println("进入hello22222222");
        return "hello2";
    }
}

总结:

方式一 方式二
实现简单 复杂
多个过滤器顺序依赖过滤器名称初始化 根据注册顺序初始化
方式二比方式一先初始化,先销毁  

   

过滤器在整个处理流程中所处位置:

https://blog.csdn.net/u013919153/article/details/104817616

发布了155 篇原创文章 · 获赞 11 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/u013919153/article/details/104819173