目录
Spring MVC的拦截器(Interceptor)是在请求处理的过程中,对请求进行拦截和处理的一种机制。拦截器可以在请求被处理前或者处理后,对请求进行一些处理,比如:日志记录、权限检查、参数校验等等。在实际开发中,拦截器是非常常用的一种技术,可以帮助我们实现很多功能。
1.拦截器的使用
在Spring MVC中,拦截器是通过实现HandlerInterceptor接口来实现的。HandlerInterceptor接口有三个方法:
- preHandle:在请求处理之前进行调用(Controller方法调用之前)。
- postHandle:在请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)。
- afterCompletion:在整个请求结束之后被调用,也就是在DispatcherServlet渲染了对应的视图之后执行(主要用于资源清理工作)。
我们可以根据需要选择实现这些方法中的一个或多个。下面是一个简单的拦截器示例:
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle方法被调用");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle方法被调用");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion方法被调用");
}
}
在上面的示例中,我们实现了HandlerInterceptor接口,并重写了三个方法。preHandle方法在请求处理之前被调用,我们可以在这里进行一些拦截逻辑,比如判断用户是否登录等。postHandle方法在请求处理之后被调用,但是在视图被渲染之前,我们可以在这里对返回的ModelAndView进行一些操作。afterCompletion方法在整个请求结束之后被调用,我们可以在这里进行一些资源清理工作。
2.配置拦截器
要想使用拦截器,我们需要在Spring MVC的配置文件中进行配置。在配置文件中,我们需要定义一个拦截器注册器,并将拦截器添加到拦截器注册器中。拦截器注册器是一个实现了WebMvcConfigurer接口的类,我们需要重写其中的addInterceptors方法,将拦截器添加到拦截器注册器中,如下所示:
@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor())
.addPathPatterns("/**") // 拦截所有请求
.excludePathPatterns("/login"); // 排除登录请求
}
}
在上面的示例中,我们定义了一个MyWebMvcConfigurer类,并重写了addInterceptors方法。在addInterceptors方法中,我们通过registry.addInterceptor方法将MyInterceptor拦截器添加到拦截器注册器中,并调用addPathPatterns方法指定需要拦截的请求路径。在这里,我们使用"**"通配符表示拦截所有请求。同时,我们也可以通过excludePathPatterns方法指定不需要拦截的请求路径,如上面的示例中排除了登录请求。
3.拦截器示例
下面是一个简单的拦截器示例,用于实现用户登录的拦截逻辑。在这个示例中,我们通过判断Session中是否存在用户信息来判断用户是否登录,如果未登录,则跳转到登录页面。
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
User user = (User)session.getAttribute("user");
if(user == null) {
// 未登录,跳转到登录页面
response.sendRedirect(request.getContextPath() + "/login");
return false;
}
return true;
}
}
在上面的示例中,我们通过request.getSession()方法获取Session对象,并通过session.getAttribute("user")方法获取Session中的用户信息。如果用户信息为null,说明用户未登录,我们则通过response.sendRedirect方法跳转到登录页面,并返回false表示拦截请求。如果用户已登录,我们则返回true表示放行请求。
在拦截器注册器中,我们可以将LoginInterceptor拦截器添加到拦截器注册器中,如下所示:
@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/**") // 拦截所有请求
.excludePathPatterns("/login"); // 排除登录请求
}
}
在上面的示例中,我们将LoginInterceptor拦截器添加到了拦截器注册器中,并通过.addPathPatterns("/**")方法指定了需要拦截的请求路径,同时通过.excludePathPatterns("/login")方法排除了登录请求。这样,当用户访问其他页面时,如果未登录,则会被拦截器拦截并跳转到登录页面。