一、拦截器及其简单说明
拦截器指的是通过拦截从浏览器发往服务器的一些请求来完成某些功能的一段程序代码,基于SpringAOP实现的,它是AOP编程思想的典型应用。在一个请求发生之前、发生时、发生后我们都可以对请求进行拦截。
拦截器可以用于:
1)权限验证:如没有登录则拦截返回登录页面;
2)解决乱码:request中设置字符集;
3)记录操作日志:记录请求信息的日志,以便进行信息监控、信息统计;
4)性能监控:如根据用户请求处理前和请求处理后的时间差计算整个请求相应完成所消耗的时间;
5)异常处理:在afterCompletion方法中可以获取异常。
二、拦截器的使用介绍
使用拦截器需要两步:自定义类继承HandlerInterceptorAdapter;在spring-mvc.xml(通常在这配置)配置bean和拦截规则
1、配置讲解
配置分为两种,一种不带拦截规则,拦截所有请求,直接配置在<mvc:interceptors>即可,如下:
<mvc:interceptors>
<bean id="myInterceptor" class="com.sl.interceptor.MyInterceptor" />
</mvc:interceptors>
<mvc:interceptors> <bean id="myInterceptor" class="com.sl.interceptor.MyInterceptor" /> <bean id="myInterceptor2" class="com.sl.interceptor.MyInterceptor2" /> <bean id="myInterceptor3" class="com.sl.interceptor.MyInterceptor3" /> </mvc:interceptors>
另一种带拦截规则,拦截指定请求,配置在<mvc:interceptors>、<mvc:interceptor>中,如下:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean id="myInterceptor" class="com.sl.interceptor.MyInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean id="myInterceptor" class="com.sl.interceptor.MyInterceptor" /> </mvc:interceptor> <bean id="myInterceptor2" class="com.sl.interceptor.MyInterceptor2" /> <bean id="myInterceptor3" class="com.sl.interceptor.MyInterceptor3" /> </mvc:interceptors>
一些配置规则参考:
<mvc:mapping path="/**"/>:拦截所有 <mvc:mapping path="/*/*"/>:拦截所有 <mvc:mapping path="/test"/>:拦截/test <mvc:mapping path="/test/"/>:拦截/test <mvc:mapping path="/test/get"/>:拦截/test/get <mvc:mapping path="/test/*"/>:拦截/test/xxx <mvc:mapping path="/test/get*"/>:拦截/test/getXXX <mvc:mapping path="/test/*List"/>:拦截/test/XXXList <mvc:mapping path="/*/get"/>:拦截/xxx/get
2、HandlerInterceptorAdapter详解
public boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) throws Exception:
该方法在action执行前执行,如果返回true,则继续执行action。如果返回false,则拦截请求。
public void postHandle(HttpServletRequest request,HttpServletResponse response,Object handler,ModelAndView modelAndView) throws Exception:
该方法在action执行后,生成视图前执行。在这里,我们有机会修改视图层数据。
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception:
最后执行,通常用于释放资源,处理异常。我们可以根据ex是否为空,来进行相关的异常处理。
3、简单演示
新建MyInterceptor.java
package com.sl.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; public class MyInterceptor extends HandlerInterceptorAdapter{ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("action之前执行1"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("action之后,生成视图之前执行1"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("最后执行,释放资源,处理异常1"); } }
新建MyInterceptor2.java
package com.sl.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; public class MyInterceptor2 extends HandlerInterceptorAdapter{ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("action之前执行2"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("action之后,生成视图之前执行2"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("最后执行,释放资源,处理异常2"); } }
新建MyInterceptor3.java
package com.sl.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; public class MyInterceptor3 extends HandlerInterceptorAdapter{ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("action之前执行3"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("action之后,生成视图之前执行3"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("最后执行,释放资源,处理异常3"); } }
配置spring-mvc.xml
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/*/get"/> <bean id="myInterceptor" class="com.sl.interceptor.MyInterceptor" /> </mvc:interceptor> <bean id="myInterceptor2" class="com.sl.interceptor.MyInterceptor2" /> <bean id="myInterceptor3" class="com.sl.interceptor.MyInterceptor3" /> </mvc:interceptors>
测试:http://localhost:8080/spring-web/test/get,拦截顺序:preHandle是正常顺序,postHandle、afterCompletion是相反的顺序