一个简单的登录拦截器
preHandle
在Controller方法处理之前调用,也是一般写拦截器的主要实现方法。
postHandle
前提:preHandle返回true。
Controller方法处理完之后,DispatcherServlet进行视图的渲染之前,也就是说在这个方法中你可以对ModelAndView进行操作
afterCompletion
前提:preHandle返回true。
DispatcherServlet进行视图的渲染之后,多用于清理资源。
代码案例
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Autowired
private RedisTemplate<String,String> redisTemplate; // redis
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
}
@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 {
boolean isLogin = false;
// 获取userID
String uid = (String) request.getSession().getAttribute("USER_ID");
// 如果含有用户id
if (StringUtils.isNoneBlank(uid)) {
// 通过userid 检测redis中是否含有sessionId
String loginSessionId = redisTemplate.opsForValue().get("SESSION:"+uid);
// redis中的sessionId 和 页面中的sessionid一致,那么就放行。
if (loginSessionId != null && loginSessionId.equals(request.getSession().getId())) {
isLogin = true;
} else {
response.setStatus(401);
// response.addHeader("message","该账号在另一台设备上登录,您被强制下线,请您重新登陆!!!");
}
} else {
if (request.getHeader("x-requested-with") != null
&& "XMLHttpRequest".equalsIgnoreCase(request.getHeader("x-requested-with"))) {
response.setStatus(403);
} else {
response.setStatus(403);
response.sendRedirect(request.getContextPath() + "/pages/login");
}
}
return isLogin;
}
}