赞
踩
过滤器(Filter),是 Servlet 规范规定的,在 Servlet 前执行的。用于拦截和处理 HTTP 请求和响应,可用于身份认证、授权、日志记录和设置字符集(CharacterEncodingFilter)等场景。
过滤器位于整个请求处理流程的最前端,因此在请求到达 Controller 层前,都会先被过滤器处理。
过滤器可以拦截多个请求或响应,一个请求或响应也可以被多个过滤器拦截。
Filter 的生命周期对应的三个关键方法:
方法 | 作用 |
---|---|
init() | 当请求发起是,会调用init()方法初始化Filter实例,仅初始化一次 ,若设置初始化参数时可调用该方法 |
doFilter() | 拦截要执行的请求,对请求和响应进行处理 |
destroy() | 请求结束时调用该方法销毁Filter的实例 |
@WebFilter(urlPatterns = "/*") public class MyFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // 用于完成 Filter 的初始化 Filter.super.init(filterConfig); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("过滤器已经拦截成功!!!"); // 执行该方法之前,即对用户请求进行预处理;执行该方法之后,即对服务器响应进行后处理。 chain.doFilter(request,response); } @Override public void destroy() { // 用于 Filter 销毁前,完成某些资源的回收; Filter.super.destroy(); } }
依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理。
SpringMVC的机制是由同一个Servlet来分发请求给不同的Controller,其实这一步是在Servlet的service()方法中执行的。所以过滤器、拦截器、service()方法,dispatc()方法的执行顺序应该是这样的
配置拦截器,实现WebMvcConfigurer接口,加@Configuration注解并重写addInterceptors方法。
@Configuration public class MyWebConfigurer implements WebMvcConfigurer { @Resource private MyHandlerInterceptor myHandlerInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { List<String> patterns = new ArrayList<>(); patterns.add("/test/handlerInterceptor"); registry.addInterceptor(myHandlerInterceptor) .addPathPatterns(patterns) // 需要拦截的请求 .excludePathPatterns(); // 不需要拦截的请求 } }
MethodInterceptor 是 AOP 中的拦截器,它拦截的目标是方法,可以不是 Controller 中的方法。
在对一些普通的方法上的拦截可以使用该拦截器,这是 HandlerInterceptor 无法实现的。
可用来进行方法级别的身份认证、授权以及日志记录等,也可基于自定义注解实现一些通用的方法增强功能。
MethodInterceptor 是基于 AOP 实现的,所以根据不同的代理有多种实现方式。
@Component
public class MyMethodInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("进入拦截,方法执行前,拦截方法是:" + invocation.getMethod().getName());
Object result = invocation.proceed();
System.out.println("方法执行后");
return result;
}
}
@Configuration public class MyMethodConfigurer { @Resource private MyMethodInterceptor myMethodInterceptor; @Bean public BeanNameAutoProxyCreator beanNameAutoProxyCreator() { // 使用BeanNameAutoProxyCreator来创建代理 BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator(); // 指定一组需要自动代理的Bean名称,Bean名称可以使用*通配符 beanNameAutoProxyCreator.setBeanNames("user*"); //设置拦截器名称,这些拦截器是有先后顺序的 beanNameAutoProxyCreator.setInterceptorNames("myMethodInterceptor"); return beanNameAutoProxyCreator; } }
过滤器是基于函数回调,拦截器是基于java的反射机制的。
过滤器是servlet规范规定的,只能用于web程序中,而拦截器是在spring容器中,它不依赖servlet容器。
过滤器可以拦截几乎所有的请求(包含对静态资源的请求),而拦截器只拦截action请求(不拦截静态资源请求)。
过滤器不能访问action上下文、值栈里的对象,拦截器可以访问action上下文、值栈里的对象。
在action的生命周期中,过滤器只能在容器初始化时被调用一次,拦截器可以多次被调用,而。
拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。
拦截器是被包裹在过滤器之中。
过滤器(Filter) :可以拿到原始的http请求,但是拿不到你请求的控制器和请求控制器中的方法的信息。
拦截器(Interceptor):可以拿到你请求的控制器和方法,却拿不到请求方法的参数。
切片(Aspect): 可以拿到方法的参数,但是却拿不到http请求和响应的对象
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。