转载请注明出处,否则侵权必究
参考文章:https://www.cnblogs.com/pypua/p/10075259.html
-
Q:什么是拦截器?
拦截器是AOP的一种实现策略
它可以动态拦截Action调用的对象
提供了一种机制,可以使开发者在Action执行前阻止其执行,也可以在action执行前后执行别的代码
-
Q:拦截器与spring的关系
拦截器是在spring容器中的,它不依赖servlet容器中,所以有分为springMVC拦截器和struts2拦截器
区别
struts2拦截器是struts提供的,配置在struts.xml中,拦截struts的Action请求并处理(拦截器只拦截action请求)。
springMVC是由spring框架提供,没有被spring管理的对象方法是不会被拦截的,所以拦截器可以获取IOC容器中的各个bean,只要注入service,就可以调用业务逻辑
-
Q:什么是拦截器链
将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用
-
Q:多个拦截器的执行顺序是怎样的的?
拦截器执行的顺序取决于配置的先后顺序,先配置的先执行,后配置的后执行
MVC拦截器只要对三个过程进行拦截校验
- 方法执行前(preHandle) 顺序
- 方法执行后(postHandler) 逆序
- 页面渲染后(afterCompletion) 逆序
比如现在有两个拦截器,那么他们的执行顺序就是
方法执行前1
方法执行前2
方法执行后2
方法执行后1
页面渲染后2
页面渲染后1
ps:当拦截器1方法执行前被拦截,则后面的拦截器链都不执行了
-
Q:拦截器是如何实现的呢?
大部分时候,拦截器方法都是通过代理的方式来调用的
Struts2的拦截器:
当请求到达Struts2的ServletDispatcher时,Struts2会查找配置文件,并根据配置实例化相对应的拦截器对象,然后串成一个list,最后一个一个调用列表中的拦截器
SpringMVC拦截器:
实现HandlerInterceptor或者继承HandlerInterceptorAdapter 来实现的
public class MyInterceptor implements HandlerInterceptor{
/**
* 在处理方法之前执行,一般用来做一些准备工作:比如日志,权限检查
* 如果返回false 表示被拦截,将不会执行处理方法
* 返回true继续执行处理方法
*/
@Override
public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {
System.out.println("执行preHandler---------"+req.getRemoteHost()+req.getRemoteUser());
resp.sendRedirect("index.jsp");
return false;
}
/**
* 在处理方法执行之后,在渲染视图执行之前执行,一般用来做一些清理工作
*/
@Override
public void postHandle(HttpServletRequest req, HttpServletResponse resp, Object handler, ModelAndView mv)
throws Exception {
System.out.println("执行postHandler");
}
/**
* 在视图渲染后执行 一般用来释放资源
*/
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println("执行afterCompletion");
}
}
配置拦截器
<mvc:interceptors>
<!-- 定义一个拦截器的配置 -->
<mvc:interceptor>
<!-- mapping 指定哪些url被拦截
/*表示根路径下的所有请求被拦截-/hello.do
/**表示根路径及其子路径下的所有请求被拦截/user/add.do
-->
<mvc:mapping path="/**"/>
<!-- 配置拦截器的路径 -->
<bean class="cn.sxt.interceptor.MyInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
拦截器是AOP的一种实现
-
Q:springBoot的拦截器如何使用
1.新建拦截器类并实现HandlerInterceptor 接口
publicclass MyInterceptor1 implements HandlerInterceptor {
@Override
publicboolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println(">>>MyInterceptor1>>>>>>>在请求处理之前进行调用(Controller方法调用之前)");
returntrue;// 只有返回true才会继续向下执行,返回false取消当前请求
}
@Override
publicvoid postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println(">>>MyInterceptor1>>>>>>>请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)");
}
@Override
publicvoid afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println(">>>MyInterceptor1>>>>>>>在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)");
}
}
2.新建配置类继承WebmvcConfigurerAdapter并重写 addInterceptors 方法
@Configuration
public class MyWebAppConfigurer
extends WebMvcConfigurerAdapter {
@Override
publicvoid addInterceptors(InterceptorRegistry registry) {
// 多个拦截器组成一个拦截器链
// addPathPatterns 用于添加拦截规则
// excludePathPatterns 用户排除拦截
registry.addInterceptor(new MyInterceptor1()).addPathPatterns("/**");
registry.addInterceptor(new MyInterceptor2()).addPathPatterns("/**");
super.addInterceptors(registry);
}
}
实例化我们自定义的拦截器,然后将对像手动添加到拦截器链中(在addInterceptors方法中添加)