登录检查拦截器

检查用户是否登录,如果没有登录,跳转到指定页面

1、配置拦截

spring用xml配置文件+拦截器实现类的方式,而springboot用WebMvcConfigurer实现类+拦截器实现类的方式
这两个配置方式用一个就行了,但是拦截器实现类是通用的

1.1 xml配置文件的方式

  • 编写xml配置文件
  • 设置要拦截的路径
  • 设置要放行的路径
  • 设置拦截器的实现类LoginInterceptor
	 <!-- 配置拦截器 -->
	 <mvc:interceptors>
	 	<mvc:interceptor>
	 		<!-- 设置当前拦截器要拦截的路径,/**拦截所有页面 -->
	 		<mvc:mapping path="/**"/>
	 		<!-- 设置不拦截的路径,不拦截这个访问地址 -->
	 		<mvc:exclude-mapping path="/admin/to/login/page.html"/>
	 		<mvc:exclude-mapping path="/admin/do/login.html"/>
	 		<mvc:exclude-mapping path="/admin/logout.html"/>
	 		<mvc:exclude-mapping path="/index.html"/>
	 		<!-- 拦截器的bean -->
	 		<bean class="com.wzw.crowd.funding.interceptor.LoginInterceptor"/>
	 	</mvc:interceptor>
	 </mvc:interceptors>

1.2 配置类的方式

  • 先编写一个拦截器实现类LoginInterceptor
  • 在实现了WebMvcConfigurer的方法中添加拦截器

2、拦截器实现类

继承HandlerInterceptorAdapter

public class LoginInterceptor extends HandlerInterceptorAdapter {

	/**
	 * 预处理回调方法,业务处理器处理请求之前被调用,实现处理器的预处理(如检查登陆),第三个参数为响应的处理器,自定义Controller
	 * 返回值:true表示继续流程(如调用下一个拦截器或处理器);false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应;
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		// 通过request对象获取HttpSession对象
		HttpSession session = request.getSession();
		
		// 从Session域尝试获取已登录用户对象,用户是存在user中,这里取出来,判断是不是空的,如果是空的就没有登录
		Admin admin = (Admin) session.getAttribute("user");
		
		// 如果没有获取到Admin对象
		if(admin == null) {
			
			// 将提示消息存入request域,存入一个提示信息
			request.setAttribute("message", "请先登录");
			
			// 转发到登录页面
			request.getRequestDispatcher("/WEB-INF/admin-login.jsp").forward(request, response);
			
			return false;
		}
		
		// 如果admin对象有效,则放行继续执行后续操作
		return true;
	}
	
	/**
	 * 后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null。
	 */
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {

	}

	/**
	 * 整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中我们可以在此记录结束时间并输出消耗时间,还可以进行一些资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中
	 */
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {

	}	
}

3、兼容ajax

  上面的内容只能对普通的页面请求有效,对异步请求例如ajax是没有效果的,就算用户已经注销,但是依旧进行操作,页面是没有任何显示的,所以这里做一下兼容ajax

3.1 pom引入

这里需要转换JSON,导入JSON包,这里用的是google的

<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.5</version>
</dependency>

3.2 JSON响应格式的实体类

  这里用了lombok,注释是lombok帮助生成了get和set方法,以及全参和无参构造函数,没有lombok就自己写get和set方法,以及全参和无参构造函数

/**
 * ajax请求的响应格式
 * 
 * @author Administrator
 *
 */
@AllArgsConstructor
@NoArgsConstructor
@Data
public class ResultEntity<T> {

	public static final String SUCCESS = "SUCCESS";
	public static final String FAILED = "FAILED";
	public static final String NO_MESSAGE = "NO_MESSAGE";
	public static final String NO_DATA = "NO_DATA";

	// 方便返回成功结果(不携带查询结果情况)
	public static ResultEntity<String> successWithoutData() {
		return new ResultEntity<String>(SUCCESS, NO_MESSAGE, NO_DATA);
	}
	
	// 方便返回成功结果(携带查询结果情况)
	public static <E> ResultEntity<E> successWithData(E data) {
		return new ResultEntity<E>(SUCCESS, NO_MESSAGE, data);
	}
	
	// 方便返回失败结果
	public static <E> ResultEntity<E> failed(E data, String message) {
		return new ResultEntity<E>(FAILED, message, data);
	}

	private String result;
	private String message;
	private T data;

}

3.3 判断是否异步请求工具类

	/**
	 * 判断请求是否为异步请求
	 * 
	 * @param request
	 * @return
	 */
	public boolean checkAsyncRequest(HttpServletRequest request) {
		//获取相应请消息头
		String accept = request.getHeader("Accept");
		String xRequested = request.getHeader("X-Requested-With");
		//判断请求消息头是否包含json的特征
		if (stringEffective(accept) && accept.contains("application/json")
				|| stringEffective(xRequested) && xRequested.contains("XMLHttpRequest")) {
			return true;
		}
		return false;
	}
	
	/**
	 * 判断字符串是否有效
	 * 
	 * @param source 待验证字符串
	 * @return true表示有效,false表示无效
	 */
	public boolean stringEffective(String source) {

		return source != null && source.length() > 0;
	}

3.4 改进后的登录拦截器

public class LoginInterceptor extends HandlerInterceptorAdapter {

	/**
	 * 预处理回调方法,业务处理器处理请求之前被调用,实现处理器的预处理(如检查登陆),第三个参数为响应的处理器,自定义Controller
	 * 返回值:true表示继续流程(如调用下一个拦截器或处理器);false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应;
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		// 通过request对象获取HttpSession对象
		HttpSession session = request.getSession();
		
		// 从Session域尝试获取已登录用户对象,用户是存在user中,这里取出来,判断是不是空的,如果是空的就没有登录
		Admin admin = (Admin) session.getAttribute("user");
		
		// 如果没有获取到Admin对象
		if(admin == null) {
			// 进一步判断当前请求是否是异步请求
			boolean checkAsyncRequest = CrowdFundingUtils.checkAsyncRequest(request);
			if (checkAsyncRequest) {
				// 创建ResultEntity对象
				ResultEntity<String> resultEntity = ResultEntity.failed(ResultEntity.NO_DATA,
						"请登录后再操作!");
				// ResultEntity对象转为JSON对象
				Gson gson = new Gson();
				String json = gson.toJson(resultEntity);
				// 这只响应的内容类型
				response.setContentType("application/json;charset=UTF-8");
				response.getWriter().write(json);
				return false;
			}
			// 将提示消息存入request域,存入一个提示信息
			request.setAttribute("message", "请登录后再操作!");
			
			// 转发到登录页面
			request.getRequestDispatcher("/WEB-INF/admin-login.jsp").forward(request, response);
			
			return false;
		}
		
		// 如果admin对象有效,则放行继续执行后续操作
		return true;
	}
	
	/**
	 * 后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null。
	 */
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {

	}

	/**
	 * 整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中我们可以在此记录结束时间并输出消耗时间,还可以进行一些资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中
	 */
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {

	}	
}

这是用layer写的,就是这个样式,没有layer的话,可以直接alert查看报错信息,不做这个改进的话,页面没有任何反应
在这里插入图片描述

4、WebMvcConfigurer实现类

springboot就用这个实现类的方式实现,spring用xml方式就行,这个就不用了

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
	
	    @Override
    public void addCorsMappings(CorsRegistry registry) {
        // 配置跨域访问
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowCredentials(true)
                .allowedMethods("*")
                .maxAge(3600);
    }
	    @Override
    public void addInterceptors(InterceptorRegistry registry) {
		/**
		* 配置自定义拦截器
		* addPathPatterns:相当于xml文件中的<mvc:mapping path="/**"/>
		* excludePathPatterns:相当于xml文件中的<mvc:exclude-mapping path="/admin/to/login/page.html"/>,可以是数组
		*/
        registry.addInterceptor(new TraceAnnotationInterceptor()).addPathPatterns("/**")
                .excludePathPatterns(trace_exclude_path);
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值