1.过滤器和拦截器简述
过滤器Filter和拦截器Interceptor, 在功能方面很类似, 但在具体实现方面差距还是比较大。
- 1.1 运行顺序不同:
Filter→Servlet→Interceptor→Controller; - 1.2 配置方式不同:
Filter在web.xml中进行配置,Interceptor在Spring的配置文件中进行配置(或注解); - 1.3 依赖环境不同:
Filter依赖于Servlet容器,而Interceptor不依赖Servlet容器; - 1.4 操作对象不同:
Filter只能对request和response进行操作,而Interceptor可对request、response、handler、modelAndView、exception进行操作(对Spring MVC生态下组件的操作能力)。
2.过滤器的配置
- 2.1 自定义过滤器,实现
Filter接口(Springboot3开始,jakarta.servlet.Filter)
import javax.servlet.*;
import java.io.IOException;public class MyFilter implements Filter {}
- 2.2 重写
doFilter,实现过滤逻辑,酌情放行
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Objects;/*** 自定义过滤器:实现根据IP统计访问次数*/
public class MyFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {// 获取访问的IPHttpServletRequest 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);}
}
- 2.3 添加
@WebFilter和@ServletComponentScan注解,实现过滤的范围配置
import javax.servlet.annotation.WebFilter;/*** 自定义过滤器:实现根据IP统计访问次数*/
@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {// 放行filterChain.doFilter(servletRequest, servletResponse);}
}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;@SpringBootApplication
@ServletComponentScan(basePackages = "com.neusoft.springboot.filter")
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}
3.拦截器的配置
- 3.1 自定义拦截器,实现
HandlerInterceptor接口
import org.springframework.web.servlet.HandlerInterceptor;public class MyInterceptor implements HandlerInterceptor {}
- 3.2 实现接口中的拦截方法(
preHandle-请求执行前、postHandler-请求执行后、afterCompletion-视图渲染后)
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Objects;public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 记录访问IP的次数逻辑// 获取访问的IPString 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;}
}
- 3.3 创建配置类,实现
WebMvcConfigurer接口,重写addInterceptors方法
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;public class InterceptorConfiguration implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {MyInterceptor myInterceptor = new MyInterceptor();registry.addInterceptor(myInterceptor).addPathPatterns("/*");}
}
4.总结
- 4.1 Filter依赖于Servlet容器,属于Servlet规范的一部分,而Interceptor依赖于SpringMVC框架;
- 4.2 Filter的生命周期由Servlet容器管理,而Interceptor通过IOC容器来管理,可通过注入等方式来获取其Bean的实例;
- 4.3 Filter可拦截所有Web资源(包括jsp,servlet,静态资源),而Interceptor则只拦截Controller。