SpringMVC拦截器
主要内容
1.简介
(1)类似于Servlet的过滤器(Filter)。
(2)给某一些请求加一定处理。
(3)在springMVC中,所有的请求都会走到前端控制器中。拦截器配合前端控制对于某一些请求进行处理。
(4)经常用于权限验证、记录请求信息的日志、判断用户是否登录等。
(5)SpringMVC的拦截器是基于Spring AOP实现的。
2.单拦截器
2.1 开发自定义的拦截器
实现HandlerInterceptor接口,重写preHandle,postHandle,afterCompletion方法。
preHandle
在handler方法处理请求之前执行。该方法返回boolean类型数据,表示如果返回true,继续执行后面的方法,如果返回false,后面的方法都不会执行。
后面的方法指的是:(1)其他的拦截器的方法(2)该拦截器的方法。(3)请求的handler方法也不会执行。
总结:
(1)如果拦截器的preHandle方法,返回false,那么其他拦截器的方法(preHandle,postHandle和afterCompletion)都不会执行。
(2)如果拦截器的preHandle方法,返回false,该拦截器的其他方法(postHandle和afterCompletion)都不会执行。例如:请求 /offer/saveOffer , prHandle方法里面的代码会在saveOffer方法执行之前执行。
(3)Controller中的方法也不会执行。
postHandle
在handler方法处理请求之后,返回ModelAndView之前执行。
afterCompletion
在完成请求之后执行。
2.2 配置拦截器。
在springMVC配置文件中配置。
(1)全局的拦截器配置
表示拦截所有的请求。
<mvc:interceptors>
<!-- 配置一个全局拦截器,拦截所有请求 -->
<bean class="interceptor.TestInterceptor"/>
</mvc:interceptors>
(2)具体的路径拦截器
*配置拦截的路径
*配置执行的拦截器类。
<mvc:interceptors>
<mvc:interceptor>
<!-- 配置拦截器作用的路径 -->
<mvc:mapping path="/**"/>
<!-- 配置不需要拦截作用的路径 -->
<mvc:exclude-mapping path=""/>
<!-- 定义在<mvc:interceptor>元素中,表示匹配指定路径的请求才进行拦截 -->
<bean class="interceptor.Interceptor1"/>
</mvc:interceptor>
<mvc:interceptor>
<!-- 配置拦截器作用的路径 -->
<mvc:mapping path="/gotoTest"/>
<!-- 定义在<mvc:interceptor>元素中,表示匹配指定路径的请求才进行拦截 -->
<bean class="interceptor.Interceptor2"/>
</mvc:interceptor>
</mvc:interceptors>
3.多拦截器
3.1 什么是多拦截器?
应用软件可用配置很多个拦截器,不同的拦截器实现不同一个功能。
3.2 开发多拦截器
和单拦截器相同,开发多个不同功能的拦截器。不同的功能实际上指的就是拦截器对于HandlerInceptor的三个方法的实现逻辑不同。
3.3 配置多拦截器
(1)配置全局的多拦截器
在mvc:interceptors 里面配置多个Bean.
(2)配置某一路径的多拦截器
在mvc:interceptors里面配置多个mvc:interceptor。
(3)在配置多个springMVC拦截器的时候,是有顺序的。按从上到下的顺序。
3.4 多拦截器的执行流程
总结:
(1)拦截器的顺序与springMVC中配置的拦截器顺序相同。
(2)先执行第一个拦截器的preHandle方法。如果preHandle1返回true。执行拦截器2的preHanle2。所有的PreHandle方法执行完了以后,并且都是true,才会执行Controller的对应方法。
(3)Controller的方法执行完了以后,先执行后面的拦截器的posthandle方法。如上图所示,先执行postHandle2,再执行postHandle1。
(4)执行完所有的拦截器的postHandle方法后,controller返回ModelAndView。
(5)Controller处理完请求以后,再执行后面的拦截器的afterCompletion方法。如上图所示,先执行afterCompletion2,再执行afterCompletion1.
4.请求拦截-登录校验实例开发
4.1 开发业务流程
访问商品管理的界面,要求用户必须先登录,如果是直接访问的用户管理的路径,使用拦截器拦截该请求,转发到登录界面。
分析:
(1)拦截器preHandle方法中来针对某一些请求需要校验用户是否已经登录。
(2)在prehandle方法中需要判断请求的路径是否需要用户登录。
(3)在prehandle方法中校验用户是否登录,判断session中是否存有该用户。
(4)如果判断用户未登录,直接将请求转发到登录界面。并且Prehandle方法返回false。
4.2 拦截器开发
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// TODO Auto-generated method stub
System.out.println("执行拦截器LoginInterceptor1的方法preHandle。。");
//判断是否为需要拦截的请求
String requestURI = request.getRequestURI();
if (requestURI.indexOf("/offer")>=0) {
//判断用户是否已经登录
if (request.getSession().getAttribute("username")==null
|| request.getSession().getAttribute("username")=="") {
//用户没有登陆,将请求转发到登陆
request.getRequestDispatcher("/login.jsp").forward(request,response);
return false;
}
}
//如果没有登录,重定向到登录页面
return true;
}
4.3 登陆controller开发
@RequestMapping("/login")
public String checkUser(User user,HttpServletRequest request) {
//判断用户名是否为admin,密码为123456
//如果是,登录成功,否则,登录失败。
if (user.getUserName().equals(“admin”)
&& user.getUserPassword().equals(“123456”)) {
request.getSession().setAttribute(“username”, “admin”);
return “forward:/offer/queryOffer”;
}
else {
return null;
}
}