SpringBoot Filter 过滤器
SpringBoot Filter 过滤器
在项目中想拦截用户的请求并执行对应的操作,Interceptor 只能拦截 Controller 层级的请求,而 Filter 则几乎能过滤所有的请求。
1、介绍
Filter 是 JavaEE 中 Servlet 规范的一个组件, 通过 Filter 技术,可以实现用户访问某个资源前,对访问的请求和响应进行过滤。
2、Filter 与 Interceptor 的区别
- 拦截器是基于 java 的反射机制,使用代理模式,而过滤器是基于函数回调。
- 拦截器不依赖 servlet 容器,过滤器依赖于 servlet 容器。
- 拦截器只能对 action 起作用,而过滤器可以对几乎所有的请求起作用(可以保护资源)。
- 拦截器可以访问 action 上下文,堆栈里面的对象,而过滤器不可以。
3、@Bean配置方式
3.1、自定义 filter 类实现 Filter 接口
import java.io.IOException;
public class AccessFilter implements Filter {
Logger logger = LoggerFactory.getLogger(AccessFilter.class);
//@Autowired失效,因为AccessFilter是new出来的
private IUserService userService;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//获取ServletContext
ServletContext context = filterConfig.getServletContext();
//获取WebApplicationContext上下文
WebApplicationContext cxt = WebApplicationContextUtils.getWebApplicationContext(context);
//完成对象注入
userService = (IUserService)cxt.getBean(IUserService.class);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
String requestUrl = request.getRequestURI();
logger.info("requestUrl:" + requestUrl);
System.out.println("=========" + userService.findById(1L).toString());
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
}
- void init(FilterConfig config):用于完成Filter的初始化。
- void destory():用于Filter销毁前,完成某些资源的回收。
- void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain): 实现过滤功能,即对每个请求及响应增加的额外的预处理和后处理。如果在doFilter中忘记调用 chain.doFilter() 方法,则用户的请求将得不到处理。
3.2、添加配置类
@Configuration
public class Config {
@Bean
public FilterRegistrationBean registrationBean() {
//创建Filter
AccessFilter filter = new AccessFilter();
FilterRegistrationBean registration = new FilterRegistrationBean();
//注册
registration.setFilter(filter);
//过滤所有请求
registration.addUrlPatterns("/*");
registration.setName("AccessFilter");
//过滤器顺序,值越小,优先级越高
registration.setOrder(1);
return registration;
}
}
如果不想添加配置类,则需要在自定义 fliter 类添加 @Component 注解进行注册。
4、@WebFilter 注解方式
4.1、自定义 filter 并添加 @WebFilter 注解
@WebFilter(filterName = "AccessFilter", urlPatterns = "/*")
@Order(1)
public class AccessFilter implements Filter {
Logger logger = LoggerFactory.getLogger(AccessFilter.class);
//@Autowired失效,因为AccessFilter是new出来的
private IUserService userService;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//获取ServletContext
ServletContext context = filterConfig.getServletContext();
//获取ebApplicationContext上下文
WebApplicationContext cxt = WebApplicationContextUtils.getWebApplicationContext(context);
//完成对象注入
userService = (IUserService)cxt.getBean(IUserService.class);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
String requestUrl = request.getRequestURI();
logger.info("requestUrl:" + requestUrl);
System.out.println("=========" + userService.findById(1L).toString());
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
}
@WebFilter 参数列表如下:
4.2 启动类添加 @ServletComponentScan 注解:
@MapperScan({"com.lin.mapper"})
@SpringBootApplication
@ServletComponentScan
public class MybatisPlusApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisPlusApplication.class, args);
}
}
参考资料1:SpringBoot之Filter
参考资料2:在Spring的过滤器中注入实体类
自我控制是最强者的本能-萧伯纳