一拦截器
一、拦截器(Interceptor)
定义:在面向切面编程中应用的,在方法执行之前或者之后,进行拦截,添加某些操作;基于java的反射机制实现的。拦截是aop的一种实现策略。
在webWork中,拦截器是动态拦截Action调用的对象,提供了一种机制使开发者可以定义在一个Action执行的前后执行的代码,也可以在一个Action执行前阻止其
执行。同时,也提供了一种可以提取Action中可重用的部分的方式。
拦截器从Action中抽出了很多功能,大量减少了Actin中的代码,抽取出的公共方法可以更好的重用。
当我们提交对Action的请求时,ServletDispatcher会根据请求,调度并执行相应的Action;在此Action执行之前,调用被Interceptor截取,Interceptor
在Action执行前后执行。
二、在ssm中的实现
SpringMVC 中的Interceptor 拦截请求是通过HandlerInterceptor 来实现的。主要有两种方式:
第一种: 定义的Interceptor类 实现Spring 的HandlerInterceptor 接口,或者是这个类继承实现了HandlerInterceptor 接口的类,比如Spring 已经提供的实现了
HandlerInterceptor 接口的抽象类HandlerInterceptorAdapter ;
第二种: 定义的Interceptor类, 实现Spring的WebRequestInterceptor接口,或者是继承实现了WebRequestInterceptor的类。
三、在springboot中的实现
第一种: 创建类 LogCostInterceptor 实现 HandlerInterceptor 接口;
创建配置类WebConfiguration 继承 WebMvcConfigurationSupport (或者 WebMvcConfigurerAdapter);添加 @Configuration注解;
@Configuration
public class WebConfiguration extends WebMvcConfigurationSupport {
private Logger logger = LoggerFactory.getLogger(WebConfiguration.class);
@Override
public void addInterceptors(InterceptorRegistry registry){
// 多个拦截器组成一个拦截器链
// addPathPatterns 用于添加拦截规则
// excludePathPatterns 用户排除拦截
registry.addInterceptor(new LogCostInterceptor()).addPathPatterns().excludePathPatterns("/swagger-ui.html");
}
}
四、 拦截器中三个方法的详细解释
SpringMvc的过滤器是链式的,在一个应用中或者一个请求中可以有多个Interceptor,执行顺序按照声明中的顺序执行,先执行每个过滤器中的preHandle方法。
1) preHandle 在请求controller之前执行,可以在方法中进行一些初始化操作或者是对当前请求的一个预处理,也可以设置一些判断决定请求是否要继续下去。
返回结果如果是true,则执行后续的Interceptor中的preHandle和controller,
如果是false,表示请求结束。
2) postHandle 在preHandle执行为true后,执行该方法。在controller执行之后,在DispatcherServlet进行视图返回渲染之前被调用;在这个方法中可以对
ModelAndView对象进行处理。postHandle的执行顺序在链式中和preHandle的执行顺序是相反的,先执行preHandle的过滤器的postHandle后执行。
3) afterCompletion preHandle执行为true后执行。 该方法在整个请求结束之后,在DispatcherServlet渲染了对应的视图之后执行。
作用: 进行资源清理工作。
二 拦截器
一 、定义:
filter 实现了 javax.servlet.filter接口的服务器端程序;
二、 用途:
设置字符集、控制权限、控制转向、业务逻辑判断等
三、 工作原理:
在web.xml文件配置需要拦截的客户端请求,它会帮你拦截到请求,此时你可以对请求或相应统一设置编码、简化操作;同时可以进行逻辑判断,如用户是否已经登录、有没有权限访问该页面等等。
随着web应用启动而启动,只需要初始化一次,以后就可以拦截相关请求,只有当web应用停止或重新部署的时候才销毁。
Filter 主要用户对用户请求进行预处理,也可以对HttpServletResponse进行后处理,是个典型的处理链。
四、 流程:
filter对用户请求进行预处理,将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。
五、 用处:
在HttpServletRequest到达Servlet之前,拦截客户的HttpServletRequest。
根据需要检查HttpServletRequest,也可以修改HttpServletRequest头和数据。
在HttpServletResponse到达客户端之前,拦截HttpServletResponse。
根据需要检查HttpServletResponse,也可以修改HttpServletResponse头和数据。
六、 种类:
用户授权的Filter:Filter负责检查用户请求,根据请求过滤用户非法请求。
日志Filter:详细记录某些特殊的用户请求。
负责解码的Filter:包括对非标准编码的请求解码。
能改变XML内容的XSLT Filter等。
Filter可以负责拦截多个请求或响应;一个请求或响应也可以被多个Filter拦截。
七、 使用:
1 创建Myfilter类继承Filter
重写 init 和 doFilter
② 在init方法中初始化自定义参数,参数名称可以设置为此时的 url,对其执行过滤,也就是放过;
③ 在doFilter中可以进行认证鉴权处理,之后执行相应的逻辑;
也可以进行跨域的设置;
在doFilter中 chain.doFilter(req, res)是对请求和响应处理的分界线,执行该方法之前,即对用户请求进行预处理;执行该方法之后,即对服务器响应进行后处理
1)第一种方案
a: 在Myfilter类 添加注解 @WebFilter ,可以添加 @Order(1)多个Myfilter的时候 按照顺序执行
@WebFilter的一些参数值
( filterName = "Myfilter", urlPatterns = "/snow/api/*",
initParams = { @WebInitParam(name = "url", value = "/snow/api/login")}
)
filterName 拦截的地址 initParams 放过的地址,不需要检测
b: 在springboot的启动类上添加 @ServletComponentScan
2)第二种方案
a: 在Myfilter类 添加注解 @Component,交给spring容器处理
b: 创建一个config类,添加注解
@Configuration
public class config {
@Bean
public FilterRegistrationBean webAuthFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(myfilte());
registration.setName("Myfilter");
registration.addUrlPatterns("/snow/api/*");
registration.addInitParameter("url", "/snow/api/login");
registration.setOrder(0); //设置顺序
return registration;
}
@Bean
public Filter myfilter() {
return new Myfilter();
}
}
三 过滤器和拦截器的比较
一、区别和不同
相同:都是AOP编程思想的实现。
不同点:
使用范围不同 过滤器只能使用再web应用程序,也就是在servlet容器中; 拦截器即可以使用在web应用中,也可以使用在
javaSE的各种环境。
使用的资源不同 拦截器是spring的组件,被spring管理,可以使用spring的任何资源包括:Servive对象、事务管理、数据源等,
通过IOC注入到容器即可。过滤器不可以。
使用的深度(范围)不同 过滤器只在Servlet前后起作用;拦截器可以深入到方法前后、异常抛出前后等,具有更大的弹性。
执行顺序不同 Filter是被Server(比如tomcat、netty)调用; Interceptor被spring调用; 所以Filter在Interceptor前面执行。
使用选择 在spring架构的实现中,优先选择使用拦截器。
二、 过滤器和拦截器的执行流程图