×

SpringMVC拦截器

我的笔记 我的笔记 发表于2018-07-23 21:26:07 浏览3131 评论0

抢沙发发表评论

一、什么是拦截器

java里的拦截器是动态拦截Controller/Action调用的对象。
它提供了一种机制可以使开发者在一个Controller执行的前后执行的代码,也可以在一个Controller执行前阻止其执行。
同时也提供了一种可以提取Controller中可重用部分的方式。
在AOP(Aspect-Oriented Programming)中拦截器用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。
 

二、实现一个拦截器

1、实现接口HandlerInterceptor创建拦截器(创建相同的拦截器1和2)
package com.qfedu.springmvc.controller.interceptor;
public class HandlerInterceptor1 implements HandlerInterceptor {

/**
* 在执行handler之前来执行的
* 用于用户认证校验、用户权限校验
*/
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {

System.out.println("HandlerInterceptor1...preHandle");

//如果返回false表示拦截不继续执行handler,如果返回true表示放行
return true;
}

/**
* 在执行handler返回modelAndView之前来执行
* 如果需要向页面提供一些公用的数据或配置一些视图信息,使用此方法实现
* 可以再次配置modelAndView
*/
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("HandlerInterceptor1...postHandle");

}

/**
* 执行handler之后执行此方法
* 如统一日志记录、方法执行性能监控:
* 在preHandle中设置一个时间点,在afterCompletion设置一个时间,两个时间点的差就是执行时长
*/
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("HandlerInterceptor1...afterCompletion");
}
}
 
2、在spring-mvc.xml中配置拦截器
<!--拦截器 -->
<mvc:interceptors>
<!--多个拦截器,顺序执行 -->
<mvc:interceptor>
<!-- /**可以拦截路径不管多少层 -->
<mvc:mapping path="/**" />
<bean class="com.qfedu.springmvc.controller.interceptor.HandlerInterceptor1"></bean>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="com.qfedu.springmvc.controller.interceptor.HandlerInterceptor2"></bean>
</mvc:interceptor>
</mvc:interceptors>
 
3、测试拦截器
 
测试1 (1 号和2号都放行)
测试结果:
HandlerInterceptor1...preHandle
HandlerInterceptor2...preHandle
 
HandlerInterceptor2...postHandle
HandlerInterceptor1...postHandle
 
HandlerInterceptor2...afterCompletion
HandlerInterceptor1...afterCompletion
 
总结:
执行preHandle是顺序执行。
执行postHandle、afterCompletion是倒序执行
 
 
测试2 (1 号放行和2号不放行)
测试结果:
HandlerInterceptor1...preHandle
HandlerInterceptor2...preHandle
HandlerInterceptor1...afterCompletion
 
总结:
如果preHandle不放行,postHandle、afterCompletion都不执行。
只要有一个拦截器不放行,controller不能执行完成
 
 
测试3 (1 、2号都不放行)
测试结果:
HandlerInterceptor1...preHandle
总结:
只有前边的拦截器preHandle方法放行,下边的拦截器的preHandle才执行。
 
 

三、实现用户认证拦截

1、确认已有login.jsp
2、确认已有index.jsp
<div><a href="login">登录</a></div>
<div>
当前用户:${sessionScope.username}
<c:if test="${sessionScope.username!=null }">
<a href="${pageContext.request.contextPath}/logout">退出</a>
</c:if>
</div>
<h1>欢迎访问</h1>
 
3、确认已有LoginController.java
4、定义拦截器:使用HandlerInterceptorAdapter
package com.qfedu.springmvc.controller.interceptor;
public class LoginInterceptor extends HandlerInterceptorAdapter {

@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {

//得到请求的url
String url = request.getRequestURI();

//判断是否是公开地址
if(url.indexOf("login")>=0){
//如果是公开 地址则放行
return true;
}

//判断用户身份在session中是否存在
HttpSession session = request.getSession();
String username = (String) session.getAttribute("username");
//如果用户身份在session中存在放行
if(username != null){
return true;
}

//执行到这里拦截,跳转到登录页面,用户进行身份认证
String contextPath = request.getContextPath();
response.sendRedirect(contextPath + "/login");

//如果返回false表示拦截不继续执行handler,如果返回true表示放行
return false;
}
}
5、配置拦截器
<mvc:interceptor>
     <mvc:mapping path="/**" />
<mvc:exclude-mapping path="/css/**"/>
<bean class="com.qfedu.springmvc.controller.interceptor.LoginInterceptor"></bean>
</mvc:interceptor>
我的笔记博客版权我的笔记博客版权