过滤器Filter
概念:Filter 过滤器,是 JavaWeb 三大组件(Servlet、Filter、Listener)之一。
过滤器可以把对资源的请求拦截下来,从而实现一些特殊的处理。
过滤器一般完成一些通用的操作,比如:登陆鉴权、统一编码处理、敏感字符处理等。
步骤:
1.定义类,实现Filter接口,并重写其所有方法。
2.在类上定义@WebFilter
注解,配置Filter拦截资源的路径。
3.在doFilter方法中执行逻辑,并放行。
4.在引导类上只用@ServletComponentScan
开启Servlet组件支持。其实就是让WebFilter生效
放行后访问对应的资源,资源访问完成后,还会回到Filter中,并执行放行后的逻辑
拦截器interceptor
概念:是一种动态拦截方法调用的机制,类似于过滤器。在Spring中动态拦截控制器中方法的执行。
作用:在指定的控制器中方法调用前后执行预先设定的代码,完成功能的增强。
步骤:
1.定义拦截器,定义注解Component, 实现Handlerlnterceptor接口,并重写其所有方法。
2.注册拦截器
拦截器和过滤器同时存在-执行流程
请求—>web服务器【 过滤器(doFilter()放行前) —> DispatcherServlet —> preHandle —> controller中定义的方法— postHandle —> afterCompletion —> (doFilter()放行后) 】—>响应
【SpringBoot中实现过滤器和拦截器】
过滤器和拦截器简述
过滤器Filter和拦截器Interceptor,在功能方面很类似,但在具体实现方面差距还是比较大的。
都是Aop思想的一种体现,用来解决项目中某一类问题是两种接口(工具),都可以对请求做一些增强
过滤器的配置
2.1 自定义过滤器,实现Filter接口(SpringBoot 3开始,jakarta.servlet.Filter)
2.2 重写doFilter,实现过滤逻辑,酌情放行
2.3 创建注解,实现过滤的范围配置
拦截器的配置
3.1 自定义拦截器,实现HandlerInterceptor接口
3.2 实现接口中的拦截方法(preHandle-请求执行前、postHandler-请求执行后、afterCompletion-视图渲染后)
3.3 创建配置类,实现WebMvcConfigure
总结
4.1 Filter依赖于Servlet容器,属于Servlet规范的一部分,而Interceptor依赖于SpringMVC框架:
4.2 Filter的生命周期由Serylet容器管理,而Interceptor通过IOC容器来管理,可通过注入等方式来获取其Bean的实例
4.3 Filter可拦截所有web资源(包括Jsp,Servlet,静态资源),而Interceptor则只拦截Controller。
案例:根据ip统计对controller的访问次数
使用过滤器实现—Servlet过滤器
1.创建filter包下MyFilter类并实现Filter接口一定要注意导入的包
2.重写doFilter
,实现过滤逻辑后放行
3.在自定义的过滤器类上加@WebFilter(urlPatterns = "/*")
注解,其中urlPatterns
的值为过滤的路径
4.在APP启动类上加上@ServletComponentScan(basePackages = "com.xnj.filter")
注解,其中basePackages
的值为过滤器的包路径
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| package com.xnj.filter;
import jakarta.servlet.*; import jakarta.servlet.annotation.WebFilter; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpSession;
import java.io.IOException; import java.util.Objects;
@WebFilter(urlPatterns = "/*") public class MyFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("放行前的逻辑"); HttpServletRequest request = (HttpServletRequest) servletRequest; String ip = request.getRemoteAddr(); HttpSession session = request.getSession(); Integer count = (Integer) session.getAttribute("count"); count = Objects.isNull(count) ? 1 : ++count; System.out.println("ip:"+ip+"\tcount:"+count); session.setAttribute("count",count); filterChain.doFilter(servletRequest, servletResponse); System.out.println("放行后的逻辑"); }
@Override public void init(FilterConfig filterConfig) throws ServletException { Filter.super.init(filterConfig); }
@Override public void destroy() { Filter.super.destroy(); } }
|
使用拦截器实现—SpringMVC拦截器
1.创建interceptor包下的MyInterceptor的自定义拦截器类并实现HandlerInterceptor
接口
2.重写preHandle
方法,请求执行前拦截,在方法内实现要执行的拦截逻辑,返回true就放行flase拦截
3.创建config包下Myconfig配置类,实现WebMvcConfigurer
接口,并在类上添加@Configuration
注解
4.配置类中重写addInterceptors
方法来注册拦截器,在registry.addInterceptor()
中添加自定义的拦截器对象
.addPathPatterns("/*")
为拦截的请求路径
.excludePathPatterns()
为排除的请求路径
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| package com.xnj.interceptor;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor;
import java.util.Objects;
@Component public class MyInterceptor implements HandlerInterceptor {
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String ip = request.getRemoteAddr(); HttpSession session = request.getSession(); Integer count = (Integer) session.getAttribute("count"); count = Objects.isNull(count) ? 1 : ++count; System.out.println("ip:"+ip+"\tcount:"+count); session.setAttribute("count",count); return true; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package com.xnj.config;
import com.xnj.interceptor.MyInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration public class MyConfig implements WebMvcConfigurer{ @Autowired private MyInterceptor myInterceptor;
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(myInterceptor).addPathPatterns("/**"); } }
|
八股—拦截器和过滤器的区别
运行顺序不同
过滤器是Servlet容器接收到请求之后,但是在Servlet容器调用之前运行的
拦截器则在Servlet被调用之后,但是在响应被发送到客户端之前运行的。
配置方式不同
过滤器是在web.xml里面去进行配置
拦截器是在spring的配置文件中去进行配置,或者使用注解的方式进行配置
Filter依赖于Servlet容器,而interceptor不依赖于Servlet容器
- Filter在过滤器中只能对request和response进行操作,而interceptor可以对request、response、handler、modelAndView、exception进行操作,相当于interceptor多了对于SpringMVC生态下的组件的一个操作能力