过滤器和SpringMVC拦截器的区别
拦截器只能拦截Controller
过滤器可以拦截任何请求.
AOP和SpringMVC拦截器的区别
Interceptor同 Filter 一样,是AOP 的具体实现(AOP切面编程只是一种编程思想而已)
拦截器是拦截发送的 请求,在 控制器 的前后添加额外功能,针对点是Controller
的方法
AOP里面的通知是在特定方法前后扩充,主要针对ServiceImpl
的方法;
SpringMvc里面拦截器是怎么写的?
有两种写法:
- implements HandlerInterceptor
- extends HandlerInterceptorAdapter
实现自定义SpringMVC拦截器的步骤:
1.新建类实现HandlerInterceptor
2. 在springmvc.xml
配置拦截器需要拦截哪些控制器
- 拦截所有控制器
- 拦截特定的的
url
1. implements HandlerInterceptor
public class DemoIntercepter implements HandlerInterceptor{
//进入控制器之前执行
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
System.out.println("preHandle:进入控制器之前执行");
//拦截的控制器的方法
System.out.println("arg2:拦截的控制器的方法:"+arg2);
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
//如果返回值是false 则阻止进入控制器
return true;
}
//控制器执行完成后进入jsp之前执行
//日志记录
//敏感词语过滤
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
System.out.println("~~~~11~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
System.out.println("postHandle:控制器执行完成进入jsp之前执行");
//拦截的控制器的方法
System.out.println("arg2:拦截的控制器的方法:"+arg2);
System.out.println("arg3:"+arg3);
String viewName = arg3.getViewName();
Object object = arg3.getModel().get("key");
System.out.println(viewName+object);
System.out.println("~~~~~22~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
}
//jsp执行完成后执行
//记录执行过程中出现的异常,无论是否出现异常该方法都会被执行
//可以把异常记录到日志中
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println("~~~~~33~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
System.out.println("afterCompletion:jsp执行完成后执行");
System.out.println("arg2:拦截的控制器的方法: "+arg2);
System.out.println("arg3:异常,根据arg3是否为null,判断是否出现异常"+arg3);
//根据arg3是否为null,判断是否出现异常
//arg3.getMessage();
System.out.println("~~~~~~44~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
}
}
springmvc.xml
<!-- 拦截器 -->
<mvc:interceptors>
<!-- 第一种配置方式 -->
<!-- <bean class="com.interceptor.DemoIntercepter"></bean> -->
<!-- 第二种配置方式 只拦截特定方式的拦截器-->
<mvc:interceptor>
<mvc:mapping path="/demo"/>
<mvc:mapping path="/demo1"/>
<bean class="com.interceptor.DemoIntercepter"></bean>
</mvc:interceptor>
</mvc:interceptors>
@Controller
public class DemoController {
@RequestMapping("demo")
public String domo() {
System.out.println("执行demo");
return "index.jsp";
}
}
结果
preHandle:进入控制器之前执行
arg2:拦截的控制器的方法:public java.lang.String com.controller.DemoController.domo()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
执行demo
~~~~11~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
postHandle:控制器执行完成进入jsp之前执行
arg2:拦截的控制器的方法:public java.lang.String com.controller.DemoController.domo()
arg3:ModelAndView: reference to view with name 'index.jsp'; model is {}
index.jspnull
~~~~~22~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
index.jsp
~~~~~33~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
afterCompletion:jsp执行完成后执行
arg2:拦截的控制器的方法: public java.lang.String com.controller.DemoController.domo()
arg3:异常,根据arg3是否为null,判断是否出现异常null
~~~~~~44~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2. extends HandlerInterceptorAdapter
@Controller
public class DemoController {
@RequestMapping("demo")
public String domo() {
System.out.println("执行demo");
return "index.jsp";
}
}
public class LoginInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
System.out.println("这里是拦截器");
return true;
}
}
<!--拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<mvc:exclude-mapping path="/resources/**" />
<mvc:exclude-mapping path="/main/**" />
<bean class="com.interceptor.LoginInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
结果
这里是拦截器
执行demo
index.jsp
拦截器栈
- 多个拦截器同时生效时,组成了拦截器栈
- 顺序:先进后出.
- 执行顺序和在
springmvc.xml
中配置顺序有关
springmvc.xml
<!-- 拦截器 -->
<mvc:interceptors>
<!-- 拦截器栈只能用这种方式-->
<bean class="com.interceptor.DemoIntercepterA"></bean>
<bean class="com.interceptor.DemoIntercepterB"></bean>
</mvc:interceptors>
- 设置先配置拦截器A 在配置拦截器B 执行顺序为
preHandle(A) --> preHandle(B) --> 控制器方法–> postHandle(B)–> postHanle(A) --> JSP --> afterCompletion(B) --> afterCompletion(A)
SpringBoot 里配置拦截器
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LogInterceptor());
registry.addInterceptor(new OldLoginInterceptor())
.addPathPatterns("/admin/oldLogin");
registry.addInterceptor(new AdminInterceptor())//
.addPathPatterns("/admin/*")//
.excludePathPatterns("/admin/oldLogin");
}
}