Filter过滤器
是Servlet的一种“加强版”,它主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理,是个典型的处理链。
- 在HttpServletRequest到达Servlet之前,拦截客户的HttpServletRequest。
- 根据需要检查HttpServletRequest,也可以修改HttpServletRequest头和数据。
- 在HttpServletResponse到达客户端之前,拦截HttpServletResponse。
- 根据需要检查HttpServletResponse,也可以修改HttpServletResponse头和数据。
主要的用途是设置字符集、控制权限、控制转向、做一些业务逻辑判断等
Filter的几个种类:
- 用户授权的Filter:Filter负责检查用户请求,根据请求过滤用户非法请求。
- 日志Filter:详细记录某些特殊的用户请求。
- 负责解码的Filter:包括对非标准编码的请求解码。
- 能改变XML内容的XSLT Filter等。
- Filter可以负责拦截多个请求或响应;一个请求或响应也可以被多个Filter拦截。
创建Filter步骤
- 创建Filter处理类,实现javax.servlet.Filter接口。
- web.xml文件中配置Filter
Interceptor拦截器
基于Java的反射机制(AOP思想)进行实现,不依赖Servlet容器。
当你提交对Action(默认是.action结尾的url)的请求时,ServletDispatcher会根据你的请求,去调度并执行相应的Action。在Action执行之前,调用被Interceptor截取,Interceptor在Action执行前后执行
SpringMVC 中的Interceptor 拦截请求是通过HandlerInterceptor 来实现的,主要有两种方式:
- 定义的Interceptor类实现了Spring 的HandlerInterceptor 接口,或者是这个类继承实现了HandlerInterceptor 接口的类
- 实现Spring的WebRequestInterceptor接口,或者是继承实现了WebRequestInterceptor的类。
package org.springframework.web.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.lang.Nullable;
public interface HandlerInterceptor {
/**
*该方法将在请求处理之前进行调用
*它返回为false 时,表示请求结束,后续的Interceptor 和Controller 都不会再执行
*/
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
/**
*在当前请求进行处理之后,也就是Controller 方法调用之后执行,但是它会在DispatcherServlet 进行视图返回渲染之前被调用
*postHandle 方法被调用的方向跟preHandle 是相反的,也就是说先声明的Interceptor 的postHandle 方法反而会后执行
*/
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
/*
*preHandle 方法的返回值为true 时才会执行
*该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作的
*/
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
拦截器(Interceptor)和过滤器(Filter)的执行顺序
过滤前-拦截前-Action处理-拦截后-过滤后
区别
作用域不同
- 过滤器依赖于servlet容器,只能在 servlet容器,web环境下使用
- 拦截器依赖于spring容器,在spring容器中调用
细粒度的不同
- 过滤器的控制比较粗,只能在请求进来时进行处理,对请求和响应进行包装
- 拦截器提供更精细的控制,可以在controller对请求处理之前或之后被调用,也可以在渲染视图呈现给用户之后调用
中断链执行的难易程度不同
- 拦截器可以 preHandle方法内返回 false 进行中断
- 过滤器就比较复杂,需要处理请求和响应对象来引发中断,需要额外的动作,比如将用户重定向到错误页面