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 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