使用Spring MVC 拦截器的原因
在controller
层操作时,经常要对用户登录信息进行判断,如果每个controller
层都写一次处理,就会出现代码重复的现象。为解决此问题,特引入Spring MVC 的拦截器 Interceptors
,对所有页面进行处理,获取用户的登录信息session
,方便后续操作。
实现步骤
- 定义
SessionInterceptor
类实现HandlerInterceptor
接口
在 HandlerInterceptor 接口中定义了三个方法来对用户的请求进行拦截处理,其中:
preHandle()
在请求处理之前调用。其返回值是布尔值Boolean,当它返回为false
时,表示请求结束,后续的Interceptor 和Controller 都不会再执行;当返回值为true
时就会继续调用下一个Interceptor 的preHandle 方法,如果已经是最后一个Interceptor 的时候就会调用当前请求的Controller方法postHandle()
当前所属的Interceptor 的preHandle 方法的返回值为true
时才能被调用。在当前请求进行处理之后,即Controller 方法调用之后、DispatcherServlet 进行视图返回渲染之前被调用。可在该方法中对Controller 处理之后的ModelAndView 对象进行操作。afterCompletion()
当前对应的Interceptor的preHandle 方法的返回值为true
时才会执行。在整个请求结束之后,即在DispatcherServlet 渲染了对应的视图之后执行。主要用于进行资源清理工作。
@Service
public class SessionInterceptor implements HandlerInterceptor {
@Autowired
private UserMapper userMapper;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 在执行实际的处理程序之前,通过获取到的cookie->token->数据库是否存在 判断用户是否登录
Cookie[] cookies = request.getCookies();
if (cookies != null && cookies.length != 0) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("token")) {
String token = cookie.getValue();
UserExample userExample = new UserExample();
userExample.createCriteria().andTokenEqualTo(token);
List<User> users = userMapper.selectByExample(userExample);
if (users.size() != 0) {
request.getSession().setAttribute("user", users.get(0));
}
break;
}
}
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
- 注册拦截器以应用于传入的请求,即将定义的拦截器配置到拦截体系中
@Configuration
//@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Autowired
SessionInterceptor sessionInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// addPathPatterns() 对哪些文件进行拦截
// excludePathPatterns() 不对哪些文件拦截
registry.addInterceptor(sessionInterceptor).addPathPatterns("/**");
}
}
- 拦截处理后,在
controller
层的操作就简单了。
User user = (User) request.getSession().getAttribute("user");
if (user == null) {
return "redirect:/";
}