拦截用户的请求,在请求的前后添加处理逻辑.
Spring MVC 的拦截器(Interceptor)与 Java Servlet 的过滤器(Filter)类似,它主要用于拦截用户的请求并做相应的处理,通常应用在权限验证、记录请求信息的日志、判断用户是否登录等功能上。
拦截器的定义
- 通过实现 HandlerInterceptor 接口或继承 HandlerInterceptor 接口的实现类(例如 HandlerInterceptorAdapter)来定义;
- 通过实现 WebRequestInterceptor 接口或继承 WebRequestInterceptor 接口的实现类来定义。
public class TestInterceptor implements HandlerInterceptor {
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("afterCompletion方法在控制器的处理请求方法执行完成后执行,即视图渲染结束之后执行");
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("postHandle方法在控制器的处理请求方法调用之后,解析视图之前执行");
}
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle方法在控制器的处理请求方法调用之前执行");
return false;
}
}
preHandle( ):控制器的处理请求方法前执行
是否中断后续操作.
postHandle( ):解析视图之前执行
请求域中的模型和视图做进一步的修改.
afterCompletion():视图渲染结束后执行
实现一些资源清理、记录日志信息等工作.
拦截器的配置
Spring MVC 的配置文件中进行配置
<!-- 配置拦截器 -->
<mvc:interceptors>
<!-- 配置一个全局拦截器,拦截所有请求 -->
<bean class="net.biancheng.interceptor.TestInterceptor" />
<mvc:interceptor>
<!-- 配置拦截器作用的路径 -->
<mvc:mapping path="/**" />
<!-- 配置不需要拦截作用的路径 -->
<mvc:exclude-mapping path="" />
<!-- 定义<mvc:interceptor>元素中,表示匹配指定路径的请求才进行拦截 -->
<bean class="net.biancheng.interceptor.Interceptor1" />
</mvc:interceptor>
<mvc:interceptor>
<!-- 配置拦截器作用的路径 -->
<mvc:mapping path="/gotoTest" />
<!-- 定义在<mvc:interceptor>元素中,表示匹配指定路径的请求才进行拦截 -->
<bean class="net.biancheng.interceptor.Interceptor2" />
</mvc:interceptor>
</mvc:interceptors>
示例⭐
1)创建 POJO 类
2)创建控制器类
创建控制器类 UserController
@Controller
public class UserController {
/**
* 登录页面初始化
*/
@RequestMapping("/toLogin")
public String initLogin() {
return "login";
}
/**
* 处理登录功能
*/
@RequestMapping("/login")
public String login(User user, Model model, HttpSession session) {
System.out.println(user.getName());
if ("bianchengbang".equals(user.getName()) && "123456".equals(user.getPwd())) {
// 登录成功,将用户信息保存到session对象中
session.setAttribute("user", user);
// 重定向到主页面的跳转方法
return "redirect:main";
}
model.addAttribute("msg", "用户名或密码错误,请重新登录! ");
return "login";
}
/**
* 跳转到主页面
*/
@RequestMapping("/main")
public String toMain() {
return "main";
}
/**
* 退出登录
*/
@RequestMapping("/logout")
public String logout(HttpSession session) {
// 清除 session
session.invalidate();
return "login";
}
}
3)创建拦截器类
创建拦截器类 LoginInterceptor
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 获取请求的URL
String url = request.getRequestURI();
// login.jsp或登录请求放行,不拦截
if (url.indexOf("/toLogin") >= 0 || url.indexOf("/login") >= 0) {
return true;
}
// 获取 session
HttpSession session = request.getSession();
Object obj = session.getAttribute("user");
if (obj != null)
return true;
// 没有登录且不是登录页面,转发到登录页面,并给出提示错误信息
request.setAttribute("msg", "还没登录,请先登录!");
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
return false;
}
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
// TODO Auto-generated method stub
}
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
// TODO Auto-generated method stub
}
}
4)配置拦截器
创建配置文件 springmvc-servlet.xml 和 web.xml
<!-- 配置拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<!-- 配置拦截器作用的路径 -->
<mvc:mapping path="/**" />
<bean class="net.biancheng.interceptor.LoginInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
5)创建视图 JSP 页面
创建 login.jsp 和 main.jsp
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>用户登录</title>
</head>
<body>
${msg }
<form action="${pageContext.request.contextPath }/login" method="post">
用户名:<input type="text" name="name" /><br>
密码:<input type="password" name="pwd" /><br>
<input type="submit" value="登录" />
</form>
</body>
</html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>用户登录</title>
</head>
<body>
${msg }
<form action="${pageContext.request.contextPath }/login" method="post">
用户名:<input type="text" name="name" /><br>
密码:<input type="password" name="pwd" /><br>
<input type="submit" value="登录" />
</form>
</body>
</html>