拦截器
发送请求时被拦截器拦截,在控制器(注解类的@RequestMapping)前后添加额外功能
拦截器和AOP区别
1. AOP在特定方法前后进行扩充(对ServiceImpl实现类)
2. 拦截器对控制器方法(对Controller注解类)
SpringMVC拦截器和Filter过滤器区别
1. SpringMVC拦截器 拦截控制器Controller
2. Filter过滤器 拦截任何请求
拦截器实现(三个方法)
新建类实现HandlerInterceptor接口
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
| public class DemoInterceptor implements HandlerInterceptor { //1. 在进入控制器之前执行(false表示阻止进入控制器) --拦截器拦截哪个控制器 @Override public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception { System.out.println("1.preHandle (控制器执行前)"); System.out.println("拦截器拦截的是:"+arg2); //arg2传的是哪个控制器 System.out.println("------------------------------------------------------"); return true; // false 表示 阻止进入控制器 } //2. 控制器执行完成,进去jsp之前执行 -- 日志记录/敏感词语过滤 @Override public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)throws Exception { System.out.println("3.postHandle (jsp之前)"); System.out.println("往"+ arg3.getViewName()+"跳转"); //arg3是跳转到哪个jsp页面 System.out.println("model的值 :"+arg3.getModel().get("model")); //获取model的值 String word = arg3.getModel().get("model").toString(); //将model的值tostring转为字符串 String neword = word.replace("祖国", "***"); //通过字符串替换 将祖国这个敏感词 换成 *** System.out.println("拦截器执行之后model过滤后: "+neword); //输出之后的model结果 System.out.println("------------------------------------------------------"); } //3. jsp执行完成后执行 -- 记录异常到日志里面 @Override public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)throws Exception { System.out.println("5.afterCompletion jsp之后"); System.out.println("现在的异常是: "+arg3); //arg3获取异常是什么 System.out.println("------------------------------------------------------"); }
}
|
spingmvc配置拦截器(两种方法)
拦截所有的控制器
1 2 3
| <mvc:interceptors> <bean class="com.bjsxt.interceptor.DemoInterceptor"></bean> </mvc:interceptors>
|
拦截特定的控制器
1 2 3 4 5 6 7
| <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/demo"/> <mvc:mapping path="/demo01"/> <bean class="com.bjsxt.interceptor.DemoInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>
|
控制器
1 2 3 4 5 6 7 8 9 10 11
| @Controller public class DemoController {
@RequestMapping("demo") public String demo(Model model) { System.out.println("2.控制器demo执行"); System.out.println("------------------------------------------------------"); model.addAttribute("model","我们都爱祖国"); // 设置model值为我们都爱祖国 return "index.jsp"; // 跳转到index.jsp页面 } }
|
主页index.jsp页面##
1 2 3 4 5 6 7 8
| <body>
<% System.out.println("4.index.jsp (jsp执行)"); System.out.println("---------------------------------------"); %> jsp执行正常!
</body>
|
总结:
方法分析(3个):
1. preHandle : 控制器前(可以获得拦截的是哪个控制器)
2. @RequestMapping的注解方法 : 控制器 (写跳转哪个jsp页面)
3. postHandle : 控制器后 jsp前(日志记录/敏感词语过滤)
4. xxx.jsp jsp页面
5. afterCompletion : jsp之后(记录异常/异常写入日志)
最终执行结果:
拦截器栈
多个拦截器同时生效 –> 拦截器栈
执行顺序(先进后出)
执行顺序和springmvc.xml里面配置的顺序有关
执行案例(两个拦截器)
配置顺序 : 拦截器A --> 拦截器B
执行顺序(圆环!!!) :
preHandle(A) 最外层
preHandle(B) 次外层
控制器方法 中心(上面都是A在前 下面都是B在前)
postHandle(B)
postHandle(A)
JSP页面
afterCompletion(B)
afterCompletion(A)