在项目中,我们会对用户请求的url统一处理,此处如果我们不用其他的管理框架,我们可以自定义拦截器,通过控制用户的请求路径进而控制用户的访问限制
自定义拦截器
/**
* 登录拦截器
* @author kexin
* @date 2018/11/09
*/
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
//如果不是映射到方法直接放过
if(!(handler instanceof HandlerMethod)) {
return true;
}
HandlerMethod checkMethod = (HandlerMethod)handler;
NotCheckedMethod methodAnno = checkMethod.getMethodAnnotation(NotCheckedMethod.class);
//如果方法存在NotCheckedMethod注解放过
if(null != methodAnno) {
return true;
}
//检查session中是否有登录用户信息
User loginUser = (User)request.getSession().getAttribute(Constant.LOGIN_USER);
if(null == loginUser) {
//拦截到的方法是ajax请求的话需要在前台JQuery.js源码中设置全局跳转页面
String XRequested =request.getHeader("X-Requested-With");
if("XMLHttpRequest".equals(XRequested)){
response.getWriter().write("noLogin#/zx/toLogin");
}else{
response.sendRedirect("/zx/toLogin");
}
return false;
}else {//检查用户是否在loginMap中状态异常
Object userStatus = GlobalVariable.loginMap.get(loginUser.getUserId());
if(!InitCodeListener.USER_STATUS_NORMAL.equals(userStatus)) {
String XRequested =request.getHeader("X-Requested-With");
if("XMLHttpRequest".equals(XRequested)){
response.getWriter().write("noLogin#/zx/toLogin");
}else{
response.sendRedirect("/zx/toLogin?userStatus="+userStatus);
}
}
}
return HandlerInterceptor.super.preHandle(request, response, handler);
}
}
自定义注解:
@Retention(RetentionPolicy.RUNTIME)//在运行时可以获取
@Target({ElementType.METHOD })//作用到方法上
public @interface NotCheckedMethod {
}
此处值得注意的是:
如果前端发来的是ajax请求,我们将无法进行请求转发,都将被返回到请求的原来的ajax方法的success中,而且是文本信息,所以此处,我们对请求进行识别,如果是ajax请求那么直接返回一个字符串,并且需要修改jquery源码,对返回的字符串进行处理,此处主要是登录情况,若session不存在了,那么就跳转到登录页面,修改代码如下:
如果要替换jQuery.js文件需要添加如下代码:
//ajax请求全局跳转到登录页面
var isJump = responses.text
if(isJump.indexOf("noLogin")>=0){
alert("登录超时");
top.location.href = isJump.substring(isJump.indexOf("#")+1);
}
位置如下图所示:(可以在jquery.js中搜索 【204】可以快速定位 )
拦截器的使用
@Configuration
public class SystemResourcesConfiguration extends WebMvcConfigurationSupport {
@Bean
public LoginInterceptor loginInterceptor() {
return new LoginInterceptor();
}
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor())//添加自定义拦截器
.addPathPatterns("/**")//拦截所有请求
.excludePathPatterns("/static/**");//静态资源放行
super.addInterceptors(registry);
}
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
//静态资源放行
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/META-INF/resources/")
.addResourceLocations("classpath:/static/")
.addResourceLocations("classpath:/resources/")
.addResourceLocations("classpath:/public/");
super.addResourceHandlers(registry);
}
//登录页面的controller
/*@Override
protected void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/zx/toLogin").setViewName("login");
super.addViewControllers(registry);
}*/
}