Springboot---过滤器
1. 拦截器与过滤器区别
AOP不是一种具体的技术,而是一种编程思想。过滤器和拦截器都属于面向切面编程的具体实现。而两者的主要区别包括以下几个方面:
- 规范不同
- Filter是在Servlet规范中定义的,依赖于Servlet容器;
- 拦截器是在Spring容器中,是Spring框架支持的;
- 使用范围不同
- Filter是Servlet规范定义的,只能应用在web程序中;
- 拦截器既可以应用在web程序中,也可以应用于Application、Swing程序中;
- 使用资源不同
- 拦截器可以获取和使用IOC容器中的各个bean,而过滤器就不行,因为拦截器是spring提供并管理的,spring的功能可以被拦截器使用,在拦截器里注入一个service,可以调用业务逻辑。而过滤器是JavaEE标准,只需依赖servlet api ,不需要依赖spring。
- 触发时机不同
Filter和拦截器触发时机不一样;
Filter是在Servlet前后起作用:Filter在请求进入容器(tomcat服务器)后,但请求进入servlet之前进行预处理;请求结束返回也是,是在servlet处理完后,返回给前端之前。
控制粒度比较粗,可以对请求和响应进行包装
拦截器:提供更精细的控制
1. preHandle:是在执行Controller之前调用;
2. postHandle:是在Controller方法调用之后处理,可以在这个方法中对Controller处理后的ModelAndView
对象进行操作;
3. afterCompletion:是在整个请求结束之后执行,一般用于资源清理工作。
1.1 小结
拦截器相比Filter有更细粒度的控制,依赖于Spring容器,可以在请求之前或之后启动,过滤器主要依赖于servlet,过滤器能做的,拦截器基本上都能做。
2. Filter使用
过滤器Filter,是在Servlet规范中定义的,是Servlet容器支持的,该接口定义在 javax.servlet
包下,主要是在客户端请求(HttpServletRequest)进行预处理,以及对服务器响应(HttpServletResponse)进行后处理。接口代码如下:
package javax.servlet;
import java.io.IOException;
public interface Filter {
void init(FilterConfig var1) throws ServletException;
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;
void destroy();
}
- init(FilterConfig): 初始化接口,在用户自定义的Filter初始化时被调用,它与Servlet的 init方法的作用是一样的。
-
doFilter(ServletRequest,ServletResponse,FilterChain): 在每个用户的请求进来时这个方法都会被调用,并在Servlet的service方法之前调用(如果我们是开发Servlet项目),而FilterChain就代表当前的整个请求链,通过调用
FilterChain.doFilter
可以将请求继续传递下去,如果想拦截这个请求,可以不调用FilterChain.doFilter,那么这个请求就直接返回了,所以Filter是一种责任链设计模式,在spring security
就大量使用了过滤器,有一条过滤器链。 - destroy: 当Filter对象被销毁时,这个方法被调用,注意,当Web容器调用这个方法之后,容器会再调用一次doFilter方法。
2.1 Filter两种使用方式:
- 使用spring boot提供的FilterRegistrationBean注册Filter
- 使用原生servlet注解(@WebFilter)定义Filter
两种方式的本质都是一样的,都是去FilterRegistrationBean注册自定义Filter
2.1.1 使用FilterRegistrationBean注册Filter
1. 自定义Filter:实现Filter接口
import javax.servlet.*;
import java.io.IOException;
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// do something 处理request 或response
System.out.println("filter1");
// 调用filter链中的下一个filter
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
2. 使用FilterRegistrationBean注册自定义Filter:
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean registrationBean() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new MyFilter());
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.setName("filter1");
return filterRegistrationBean;
}
}
2.1.2 使用@WebFilter注解
// 注入spring容器
@Component
// 定义filterName 和过滤的url
@WebFilter(filterName = "my2Filter" ,urlPatterns = "/*")
public class My2Filter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("filter2");
}
@Override
public void destroy() {
}
}
上一篇: 登录、注册小练习
下一篇: mybatis中dtd文件找不到