拦截器:
拦截器是web项目中高频率使用的,主要用于
处理web请求中的一些通用性问题,共性问题在拦截器中处理,可以减少代码的重复,便于维护
SpringMvc中拦截器的实现主要有3步:
1.编写拦截器类实现HandlerInterceptor接口
2.将拦截器注册进SpringMvc框架中
3.配置拦截器的拦截规则
第一步实现HandlerInterceptor接口:会生成3个接口方法
postHandle:在请求被处理之前进行调用
preHandle:在请求被处理之后进行调用
afterCompletion:在请求结束之后进行调用
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
/**
* @author Administrator
*拦截器的实现:
*1.编写拦截器类实现HandlerInterceptor接口
*2.将拦截器注册进SpringMvc框架中
*3.配置拦截器的拦截规则
*
*/
public class Test1Interceptor implements HandlerInterceptor{
//第三执行
//方法执行后执行的,经常用来关闭一下方法,比如io流,数据库连接等
@Override
public void afterCompletion(HttpServletRequest arg0,
HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println("执行到了afterCompletion方法");
}
//第二执行
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2, ModelAndView arg3) throws Exception {
// TODO Auto-generated method stub
System.out.println("执行到了postHandle方法");
//可以通过ModelAndView参数改变显示的视图,或修改发往视图的方法
arg3.addObject("msg", "拦截器修改为: 李四用户");
arg3.setViewName("/test.jsp");
}
//先执行
//返回值,表示我们是否需要将当前的请求拦截下来
//如果返回false,请求将会被终止,
//如果返回true,请求将会被继续执行
//arg2表示被拦截的目标的对象
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2) throws Exception {
// TODO Auto-generated method stub
System.out.println("执行到了preHandle方法");
return true;
}
}
第二步注册SpringMVC框架
需要再SpringMvc框架中设置命名空间
xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
以及xsd命名空间
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
注册拦截器
<mvc:interceptors>
<mvc:interceptor>
<--配置规则 !-->
<mvc:mapping path="/index.jsp"/>
<bean class="com.interceptor.Test1Interceptor"/>
</mvc:interceptor>
</mvc:interceptors>
不设置拦截器规则前:随便访问一个请求都会在控制台打印输出语句
执行到了preHandle方法
执行到了postHandle方法
执行到了afterCompletion方法
设置完成规则后,只有访问index.jsp的时候才会触发拦截器
多个拦截器配置:
比如设置拦截器1,和拦截器2.
<mvc:interceptors>
<bean class="com.interceptor.Test1Interceptor"/>
<bean class="com.interceptor.Test2Interceptor"/>
</mvc:interceptors>
再访问后的方法执行顺序为:
preHandle1,preHandle2,postHandle2,postHandle1,afterCompletion2,afterCompletion1
就像收费站一样,当你通过收费站1(preHandle1),再经过收费站2(preHandle2),到达目的地,再返回的时候经过收费站2(postHandle2),再经过收费站1(postHandle1),然后到家,随后从收费站拿到的发票就先拿到了收费站2的发票(afterCompletion2)然后又拿到收费站1的发票(afterCompletion1)
拦截器还可通过实行WebRequestInterceptor接口来编写
方法也一样的,向SpringMVC注册的写法不变,
唯一不同的是preHandle方法没有了boolean返回值,无法终止请求,项目中也不常使用
拦截器使用场景:
使用原则:处理所有请求的共同问题
1.拦截器解决乱码问题
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2) throws Exception {
// TODO Auto-generated method stub
System.out.println("执行到了preHandle方法");
//设置编码格式
arg0.setCharacterEncoding("UTF-8");
return true;
}
2.解决权限验证问题
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2) throws Exception {
// TODO Auto-generated method stub
System.out.println("执行到了preHandle方法");
arg0.setCharacterEncoding("UTF-8");
if(arg0.getSession().getAttribute("user")==null){
//如果用户没有登录,就终止请求,然后发送到登录页面
arg0.getRequestDispatcher("/login.jsp").forward(arg0, arg1);
return false;
}
return true;
}
拦截器与过滤器的区别
过滤器Filter依赖于Servlet容器,基于回调函数,过滤范围较大
拦截器Interceptor依赖于框架容器,基于反射机制,只过滤请求