1. 概念
springMVC的处理器拦截器类似于servlet的过滤器Filter,用于对处理器进行预处理和后处理。
2. 拦截器定义
在SpringMVC中定义拦截器很简单,只需要实现HandlerInterceptor接口即可。
public class MyInteceptor implements HandlerInterceptor{
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println("afterCompletion...");
}
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
System.out.println("postHandle...");
}
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
System.out.println("preHandle...");
// 返回true或者false,表示放行或者拦截的意思
return true;
}
}
3. 配置拦截器
在pringMVC.xml中的最后面加入如下配置内容:
<!-- 拦截器定义 -->
<mvc:interceptors>
<!-- 定义一个拦截器 -->
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.bjc.mvc.inteceptor.MyInteceptor" />
</mvc:interceptor>
</mvc:interceptors>
注意:
1. 拦截器的配置一般位于配置的最后面
2. 关于path的配置的说明:
2.1 /** :表示拦截所有的请求,包括二级以上的目录
2.2 /* :拦截所有请求,但是不包括二级以上目录
4. 单个拦截器的执行顺序
按照先后分别执行:
preHandle(只有该方法返回true的时候,才会往下执行) ——>controller业务方法——>postHandle——>afterCompletion
1. preHandle通常可以用作登录拦截,权限拦截
2. postHandle在方法执行之后返回ModelAndView之前执行,通常可以用作设置页面的公用参数设置。
3. afterCompletion在方法执行之后被执行,通常可以处理异常或者清理资源和用作日志记录等操作。
5. 多个拦截器的执行顺序
5.1 多个拦截器的配置
<mvc:interceptors>
<!-- 定义一个拦截器 -->
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.bjc.mvc.inteceptor.MyInteceptor" />
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.bjc.mvc.inteceptor.MyInteceptor2" />
</mvc:interceptor>
</mvc:interceptors>
5.2 执行顺序
按照拦截器的配置顺序执行
1. 执行 preHandle1——>执行preHandle2
2. 执行Controller方法
3. 执行postHandle2——>执行postHandle1
4. 执行afterCompletion2——>执行afterCompletion1
注意:只要A拦截器做了放行,那么对应A的afterCompletion一定会被执行。
6. 拦截器应用——登录拦截器(案例)
6.1 Controller
@Controller
@RequestMapping("user")
public class UserController {
@RequestMapping("toLogin")
public String toLogin(){
return "login";
}
@RequestMapping("login")
public String login(String username,String password,HttpSession session){
if(username.equals("admin")){
session.setAttribute("username", username);
return "redirect:/itemList.action";
}
return "login";
}
}
6.2 定义拦截器
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
/**
* 登录拦截器
* @author Steven
*
*/
public class LoginInterceptor implements HandlerInterceptor {
//方法执行后被执行
//处理异常,清资源,记录日志等等
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
}
//方法执行之后,返回ModelAndView之前被执行
//设置页面的共用参数等等
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
}
//进入方法前被执行
//登录拦截,权限验证等等
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
//判断用户有没有登录
Object object = request.getSession().getAttribute("username");
if(object == null){
response.sendRedirect(request.getContextPath() + "/user/toLogin.action");
}
//true放行,false拦截
return true;
}
}
6.3 配置拦截器
<mvc:interceptor>
<!-- /**拦截所有请求,包括二级以上目录 -->
<mvc:mapping path="/**"/>
<!-- 配置不拦截目录 -->
<mvc:exclude-mapping path="/user/**"/>
<bean class="com.bjc.springmvc.interceptor.LoginInterceptor" />
</mvc:interceptor>
注意:登录拦截器不能拦截用户登录请求,所以,需要加上 <mvc:exclude-mapping path="/user/**"/> 过滤掉/user/**的请求。