SpringMVC之拦截器

一、拦截器概述

SpringMVC的拦截器(Interceptor)与java Servlet的过滤器(Filter)类似,用于拦截用户的请求并且做出相应的处理。一般应用于权限认证、记录请求信息的日志、判断用户是否登陆等功能。

(一)拦截器的实现方式

 一种是通过实现 Handlerlnterceptor 接口; 另一种是通过实现 WebRequestlnterceptor 接口。

以实现 Handlerlnterceptor 接口的定义方式为例,自定义拦截器类的代码如下所示。

public class TestInterceptor implements HandlerInterceptor{
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("preHandle方法在控制器处理请求方法前执行");
		/**
		 * 返回值为true表示继续向下执行,false表示中断后续操作
		 */
		return true;
	}
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println("postHandle 方法在控制器的处理请求方法调用之后,解析视图之前执行");

	}
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		System.out.println("afterCompletion 方法在视图渲染结束之后执行,即最后执行");
	}
}

• preHandler方法:该方法会在控制器方法前执行,其返回值表示是否中断后续操作。
• postHandle方法:该方法会在控制器方法调用之后,且解析视图之前执行。 可以通过此 方法对请求域中的模型和视图做出进一步的修改。
• afterCompletion方法:方法会在整个请求完成,即视图渲染结束之后执行。 可以通过此方法实现一些资源清理、记录曰志信息等工作。

(二) 拦截器的配置

要使自定义的拦截器类生效,还需要在 Spring MVC 的配置文件中进行配置。配置代码如下:

<!-- 配置拦截器 -->
	<mvc:interceptors>
		<!-- 配置一个全局拦截器,拦截所有的请求 -->
		<bean class="interceptor.LoginInterceptor"></bean>
		<mvc:interceptor>
			<!-- 配置拦截器的作用路径 -->
			<mvc:mapping path="/**"/>
			<!-- 配置不需要拦截的路径 -->
			<mvc:exclude-mapping path=""/>
			<!-- 定义在<mvc:interceptor>下面的,表示对匹配路径的请求才进行拦截 -->
			<bean class="interceptor.LoginInterceptor"></bean>
		</mvc:interceptor>
	</mvc:interceptors>

注意:
1、拦截器bean类所放的位置决定拦截器是全局拦截器还是局部拦截器
2、<mvc:mapping path="/gotoTest"/>表示拦截以/gotoTest结尾的路径
3、 mvc:interceptor 中的子元素必须严格按照 <:mvc:mapping … />、<mvc:exclude-mapping … />、<bean … />的顺序。

二、拦截器的执行流程

(一)单个拦截器的执行流程

1、控制器类InterceptorController

@Controller
public class InterceptorController {
	@RequestMapping("/gotoTest")
	public String gotoTest() {
		System.out.println("Controller正在测试拦截器,执行控制器的处理请求方法!");
		return "test";
	}
}

2、拦截器类

public class TestInterceptor implements HandlerInterceptor{
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("preHandle方法在控制器处理请求方法前执行");
		/**
		 * 返回值为true表示继续向下执行,false表示中断后续操作
		 */
		return true;
	}
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println("postHandle 方法在控制器的处理请求方法调用之后,解析视图之前执行");

	}
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		System.out.println("afterCompletion 方法在视图渲染结束之后执行,即最后执行");
	}
}

3、Springmvc-servlet.xml

<!-- 使用扫描机制扫描控制器类 -->
	<context:component-scan base-package="com.controller"></context:component-scan>
	<!-- 配置视图解析器 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" 
			id="internalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/views/"></property>
		<property name="suffix" value=".jsp"></property>
	</bean>
	<!-- 配置拦截器 -->
	<mvc:interceptors>
		<!-- 配置一个全局拦截器,拦截所有的请求 -->
		<bean class="interceptor.LoginInterceptor"></bean>
	</mvc:interceptors>

4、运行结果
在这里插入图片描述

(二)多个拦截器的执行流程

1、控制器和拦截器上同
2、Springmvc-servlet.xml文件的配置

<mvc:interceptors>
		<mvc:interceptor>
			<!-- 配置拦截器的作用路径 -->
			<mvc:mapping path="/**"/>
			<!-- 定义在<mvc:interceptor>下面的,表示对匹配路径的请求才进行拦截 -->
			<bean class="interceptor.Interceptor1"></bean>
		</mvc:interceptor>
		<mvc:interceptor>
			<!-- 配置拦截器的作用路径 -->
			<mvc:mapping path="/gotoTest"/>
			<bean class="interceptor.Interceptor2"></bean>
		</mvc:interceptor>
	</mvc:interceptors>

3、运行结果
在这里插入图片描述

多个拦截器在执行的过程中,preHandle方法按照配置文件中拦截器的配置顺序执行,而postHandle和afterCompletion方法则按照配置文件的反序执行。

三、应用案列——用户登录权限验证

1、创建POJO类

public class User {
	private String uname;
	private String upwd;
	//省略getter和setter方法
}

2、创建控制器类

@Controller
public class UserController {
	/**
	 *  登录页面初始化
	 */
	@RequestMapping("/tologin")
	public String initLogin() {
		return "login";
	}
	/**
	 * 处理登录功能
	 */
	@RequestMapping("/login")
	public String login(User user,Model model,HttpSession session) {
		System.out.println("用户名:"+user.getUname());
		if("juhaijun".equals(user.getUname())
				&&"123456".equals(user.getUpwd())) {
			
			session.setAttribute("user", user);
			return "redirect:main";
		}
		model.addAttribute("msg", "用户名或密码错误");
		System.out.println("用户名或密码错误!");
		return "login";
	}
	/**
	 * 跳转到主页面
	 */
	@RequestMapping("/main")
	public String toMain() {
		return "main";
	}
	/**
	 * 退出登录
	 */
	@RequestMapping("/logout")
	public String logout(HttpSession session) {
//		清除session
		session.invalidate();
		return "login";
	}
}

3、创建拦截器类

public class LoginInterceptor implements HandlerInterceptor{
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
//		获取登陆的url
		String url= request.getRequestURI();
		System.out.println("请求路径为:"+url);
//		登录界面不进行拦截
		if(url.indexOf("/tologin")>=0 || url.indexOf("/login")>=0) {
			return true;
		}
//		获取session
		HttpSession session = request.getSession();
		Object obj = session.getAttribute("user");
		if(obj != null) {
		//处于登录状态
			return true;
		}
//		未登录状态
		request.setAttribute("msg", "用户还未登陆,请先登录");
		request.getRequestDispatcher("/WEB-INF/views/login.jsp").forward(request, response);
		return false;
	}
}

4、创建jsp页面——登录页面和主界面

<body>
	${msg }
	<form action="${pageContext.request.contextPath }/login" method="post">
		
		用户名:<input type="text" name="uname"/>
		密码:<input type="password" name="upwd"/>
		<input type="submit" value="登录"/>
	</form>
</body>
<body>
	当前用户:${user.uname }<br>
	<a href="${pageContext.request.contextPath }/logout">退出</a>
</body>

5、运行结果
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

四、拦截器小结

我们应当熟悉拦截器在单个执行和多个执行流程下的区别,着重掌握Springmvc配置文件的配置流程。深入理解拦截器在上述应用案列中的作用。如有不足,多谢各位斧正。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值