1. 程式人生 > >spring boot系統登入實現自定義攔截器

spring boot系統登入實現自定義攔截器

在專案中,我們會對使用者請求的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);
	}*/
}