Springboot 过滤器和拦截器详解及使用场景,nginx 原理和架构
1、过滤器和拦截器触发时机不一样,过滤器是在请求进入容器后,但请求进入 servlet 之前进行预处理的。请求结束返回也是,是在 servlet 处理完后,返回给前端之前。
2、拦截器可以获取 IOC 容器中的各个 bean,而过滤器就不行,因为拦截器是 spring 提供并管理的,spring 的功能可以被拦截器使用,在拦截器里注入一个 service,可以调用业务逻辑。而过滤器是 JavaEE 标准,只需依赖 servlet api ,不需要依赖 spring。
3、过滤器的实现基于回调函数。而拦截器(代理模式)的实现基于反射
4、Filter 是依赖于 Servlet 容器,属于 Servlet 规范的一部分,而拦截器则是独立存在的,可以在任何情况下使用。
5、Filter 的执行由 Servlet 容器回调完成,而拦截器通常通**过动态代理(反射)**的方式来执行。
6、Filter 的生命周期由 Servlet 容器管理,而拦截器则可以通过 IoC 容器来管理,因此可以通过注入等方式来获取其他 Bean 的实例,因此使用会更方便。
过滤器和拦截器非常相似,但是它们有很大的区别
最简单明了的区别就是**过滤器可以修改 request,而拦截器不能
过滤器需要在 servlet 容器中实现,拦截器可以适用于 javaEE,javaSE 等各种环境
拦截器可以调用 IOC 容器中的各种依赖,而过滤器不能
过滤器只能在请求的前后使用,而拦截器可以详细到每个方法**
区别很多,大家可以去查下
总的来说
过滤器就是筛选出你要的东西,比如 requeset 中你要的那部分
拦截器在做安全方面用的比较多,比如终止一些流程
网上有一张图片很不错,这里拷过来给大家看一下
过滤器(Filter) :可以拿到原始的 http 请求,但是拿不到你请求的控制器和请求控制器中的方法的信息。
拦截器(Interceptor):可以拿到你请求的控制器和方法,却拿不到请求方法的参数。
切片(Aspect): 可以拿到方法的参数,但是却拿不到 http 请求和响应的对象
二、过滤器
=====
两种方式:?
1、使用 spring boot 提供的 FilterRegistrationBean 注册 Filter?
2、使用原生 servlet 注解定义 Filter?
两种方式的本质都是一样的,都是去 FilterRegistrationBean 注册自定义 Filter
方式一: (使用 spring boot 提供的 FilterRegistrationBean 注册 Filter )
①、先定义 Filter:
package com.corwien.filter;
import javax.servlet.*;
import java.io.IOExcepti
on;
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
// doFilter()方法中的 servletRequest 参数的类型是 ServletRequest,需要转换为 HttpServletRequest 类型方便调用某些方法
System.out.println("filter1"); // 调用 filter 链中的下一个 filter
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
String ip = request.getRemoteAddr();
String url = request.getRequestURL().toString();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d = new Date();
String date = sdf.format(d);
System.out.printf("%s %s 访问了 %s%n", date, ip, url);
filterChain.doFilter(request, response);
}
@Override public void destroy() {
}
}
②、注册自定义 Filter
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean registrationBean() {
** FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new** MyFilter());
filterRegistrationBean.addUrlPatterns("/*");
return filterRegistrationBean;
}
}
方式一的①②步骤可以用下面这段代码代替:
@Configuration public class FilterConfig {
@Bean public FilterRegistrationBean registFilter() {
FilterRegistrationBean registration **= new FilterRegistrationBean();
registration.setFilter(new** LogCostFilter());
registration.addUrlPatterns("/*");
registration.setName("LogCostFilter");
registration.setOrder(1); return registration;
}
}
public class LogCostFilter implements Filter {
@Override public void init(FilterConfig filterConfig) throws ServletException {
}
@Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { long start = System.currentTimeMillis();
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("Execute cost="+(System.currentTimeMillis()-start));
}
@Override public void destroy() {
}
方式二:(使用原生 servlet 注解定义 Filter?)
// 注入 spring 容器
@Component // 定义 filterName 和过滤的 url
@WebFilter(filterName = "my2Filter" ,urlPatterns = "/*") public class My2Filter implements Filter {
评论