拦截器
springmvc提供了拦截器,类似于过滤器, 他将在请求具体处理之前先做检查,有权决定接下来是否继续。还可以对请求进行加工。
拦截器可是设计多个,
通过实现HandlerInterceptor接口,定义了三个方法
- 前置处理
- 后置处理
- 完成处理
案例一
拦截器实现方法耗时统计与警告
后台代码
package com.text.interceptors;
import org.apache.log4j.Logger;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/*
* 方法耗时统计的拦截器
* */
public class MethodTimerInterceptor implements HandlerInterceptor {
//获得
private static final Logger LOGGER = Logger.getLogger(MethodTimerInterceptor.class);
//前置功能 开始到结束,做个减法
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//1 定义开始时间
long start = System.currentTimeMillis();
//2 将其存到请求域当中
request.setAttribute("start",start);
//记录请求日志
LOGGER.info(request.getRequestURI() + ",请求到达");
//返回true,才会找下一个拦截器,如果没有下一个拦截器,则去Controller
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//1 取出start
long start = (long) request.getAttribute("start");
//2 得到end
long end = System.currentTimeMillis();
//3 记录一下耗时
long spendTime = end - start;
if(spendTime>=1000){
LOGGER.warn("方法耗时严重,请及时处理,耗时:"+ spendTime + "毫秒");
}else{
LOGGER.info("方法耗时:"+spendTime+"毫秒,处理时间正常");
}
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
springmvc配置
<!--拦截器的配置-->
<mvc:interceptors>
<mvc:interceptor>
<!--
/*的写法只能拦截/name方法,只能有一层,不能多层拦截
-->
<mvc:mapping path="/**/*"/>
<bean class="com.text.interceptors.MethodTimerInterceptor">
</bean>
</mvc:interceptor>
<mvc:interceptor>
<!--
只想拦截/user/**/*
还需开方登录权限
-->
<mvc:mapping path="/user/**/*"/>
<!--还要排除登录的URI-->
<mvc:exclude-mapping path="/user/login"/>
<bean class="com.text.interceptors.SessionInterceptor">
</bean>
</mvc:interceptor>
</mvc:interceptors>
案例二
一个会话拦截器,用于检验该用户是否有登录权限
后台代码
package com.text.interceptors;
import com.text.pojo.User;
import org.apache.log4j.Logger;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 会话拦截器
*/
public class SessionInterceptor implements HandlerInterceptor {
private static final Logger LOGGER = Logger.getLogger(SessionInterceptor.class);
//检查当前会话是否有User,如果有,放行,如果没有就不放行
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object user = request.getSession().getAttribute("SESSION_USER");
if(user == null){
LOGGER.warn("您不具备权限,请重新登录");
return false;
}
if(user instanceof User){
//再去数据库检查其身份对不对
User u = (User) user;
u.setPassword(null);
request.getSession().setAttribute("SESSION_USER",u);
LOGGER.info(u.getUsername() + "处于登录状态,可以执行操作");
return true;
}else {
LOGGER.warn("请不要搞事,请重新登录");
return false;
}
}
}
springmvc配置
<mvc:interceptors>
<mvc:interceptor>
<!--
只想拦截/user/**/*
还需开方登录权限
-->
<mvc:mapping path="/user/**/*"/>
<!--还要排除登录的URI-->
<mvc:exclude-mapping path="/user/login"/>
<bean class="com.text.interceptors.SessionInterceptor">
</bean>
</mvc:interceptor>
</mvc:interceptors>
其它事项
springmvc配置
<mvc:interceptors>结点下可以放多个拦截器,按照从上到下的顺序一个个拦截
拦截器执行顺序问题
如果有n个拦截器,并且都能拦截到某个URL的时候,执行顺序问题
在springmvc当中拦截器定义的顺序是有关系的,配在前面的优先去拦截
如i1 i2 i3
前置处理i1 i2 i3
后置处理i3 i2 i1
拦截器与过滤器的比较
相似
都有优先处理请求的权利,可以决定是否将请求转移到实际处理的控制器,都可以对请求或者会话中的请求进行加工
不同
拦截器可以做前置处理,亦可以做后置处理,还可以完成后处理,控制更加细致一些,过滤器只负责前面和后面的过滤行为
过滤器优先执行,过滤器是servlet规范里的组件,而拦截器是框架自己额外添加的组件