“芣苢春来盈女手,梧桐老去长孙枝”
简介:
Spring MVC中的 Interceptor拦截器拦截请求是通过实现Handlerlnterceptor接口来完成的。在 Spring MVC中定义一个 Interceptor拦截器非常简单,通常在要定义的 Interceptor拦截器类中实现 Spring的 Handlerlnterceptor接口。
Handlerlnterceptor接口中定义了三个方法, Spring MVC就是通过这三个方法来对用户的请求进行拦截处理的。这三个方法将在接下来的代码中注释解析;
实现:
- 配置Spring MVC配置文件:
<!--springMVC拦截器定义-->
<mvc:interceptors>
<mvc:interceptor>
<!--拦截所有请求-->
<mvc:mapping path="/*"/>
<!--使用bean定义一个Interceptor-->
<bean class="org.arunner.interceptor.AuthorizationInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
- 实现HandlerInterceptor 接口:
import org.fkit.domain.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author aRunner
* @date 2018/11/4
* 拦截器必须实现HandlerInterceptor接口
*/
public class AuthorizationInterceptor implements HandlerInterceptor {
//不拦截"/loginForm"和"/login"请求
private static final String[] IGNORE_URI = {"/loginForm","/login"};
//preHandle方法是进行处理器拦截用的,该方法将在Controller处理之前进行调用,
// 该方法的返回值为true拦截器才会继续往下执行,该方法的返回值为false的时候整个请求就结束了
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("AuthorizationInterceptor preHandle -- >");
//flag变量用于判断用户是否登录,默认为false
boolean flag = false;
//获取请求的路径进行判断
String servletPath = request.getServletPath();
//判断请求是否是否需要拦截
for(String s : IGNORE_URI) {
if (servletPath.contains(s)){
flag = true;
break;
}
}
//拦截请求
if (!flag) {
//1.获取session中的用户
User user = (User) request.getSession().getAttribute("user");
//2.判断用户是否已经登录
if (user == null) {
//如果用户没有登录,则设置提示信息,跳转到登录页面
System.out.println("AuthorizationInterceptor拦截请求");
request.setAttribute("message","请先登录再访问网站");
request.getRequestDispatcher("loginForm").forward(request,response);
}else {
//如果用户已经登录,则验证通过,放行
System.out.println("AuthorizationInterceptor放行请求");
flag = true;
}
}
return flag;
}
//该方法将在Controller的方法调用之后执行,方法中可以对ModelAndView进行操作,
// 该方法也只能在当前Interceptor的preHandler方法的返回值为true时才会执行
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("AuthorizationInterceptor postHandle -- >");
}
//该方法在整个请求完成之后执行,主要作用是用于清理资源,
// 该方法也只能在当前的Interceptor的preHandler方法的返回值为true时才会执行
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("AuthorizationInterceptor afterConpletion -- >");
}
}
- 处理登录的请求和动态跳转地址:
//处理login请求
@RequestMapping(value = "login")
public ModelAndView login(String loginname, String password, ModelAndView mv, HttpSession session) {
//模拟数据库根据登录名和密码查找用户,判断用户登录
if (loginname != null && loginname.equals("arunner") && password != null && password.equals("123456")){
//模拟创建用户
User user = new User();
user.setLoginname(loginname);
user.setPassword(password);
user.setUsername("管理员");
//登录成功,将user对象设置到HttpSession作用域
session.setAttribute("user",user);
//转发到main请求
mv.setViewName("redirect:main");
}else {
//登录失败,设置失败提示信息,并跳转到登录页面
mv.addObject("message","登录名或密码错误,请重试");
mv.setViewName("loginForm");
}
return mv;
}
@Request
Mapping(value = "/{formName}")
public String loginForm(@PathVariable String formName,Model model) {
//动态跳转页面
return formName;
}
启动项目,查看控制台输出:
- 第一次没有登录时,直接访问main请求,看控制台的输出:
- 请求被我们定义的拦截器拦截,然后跳转到登录页面:
- 在登录页面,我们使用正确的用户名和密码登录之后,再看控制台的输出:
这次是放行请求。说明我们自定义的拦截器效果显著。