拦截器-Interceptor
- 拦截器(Interceptor)用于对URL请求进行前置/后置过滤
- Interceptor与Filter用途相似,但实现方式不同
- Interceptor底层就是基于Spring AOP面向切面编程实现
拦截器开发流程
- Maven依赖servlet-api
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<!--只有在开发编译的时候才会引用,最终打包发布的时候这个jar会被排除在外-->
<scope>provided</scope>
</dependency>
- 创建一个新的类实现HandlerInterceptor接口
public class MyInterceptor implements HandlerInterceptor {
//preHandle - 前置执行处理
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println(request.getRequestURI()+"-准备执行");
/*
* 返回的为true,请求将会被送往后面的拦截器或者控制器
* 返回为false当前响应会被阻止,直接产生响应返回客户端
* return的结果决定了请求继续执行还是返回响应返回客户端
*/
return true;
}
//postHandle - 目标资源已被Spring MVC框架处理成功没有产生响应文本执之前需要执行的代码
//目标URL被执行完了之后就会指向当前拦截
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println(request.getRequestURI()+"-目标处理成功");
}
//afterCompletion - 响应文本已经生成,产生响应文本之后执行,永远都是最后执行的方法
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println(request.getRequestURI()+"-响应内容以产生");
}
}
- applicationContext配置过滤地址
<mvc:interceptors>
<mvc:interceptor>
<!--对所有的请求进行拦截,并且送往MyInterceptor并以MyInterceptor中实现的方法依次执行-->
<mvc:mapping path="/**"/>
<bean class="fun.afterglow.restful.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
拦截器细节
静态资源的处理
当一个URI被多个拦截器同时拦截时,前置处理执行先后顺序将以配置顺序为准,后置处理为反方向
<!--代表需要排除的资源有哪些,可以创建一个静态资源目录放所有的静态资源-->
<mvc:exclude-mapping path="resources/**"/>
--------------------------------
<mvc:interceptors>
<mvc:interceptor>
<!--对所有的请求进行拦截,并且送往MyInterceptor并以MyInterceptor中实现的方法依次执行-->
<mvc:mapping path="/**"/>
<!--代表需要排除的资源有哪些,可以创建一个静态资源目录放所有的静态资源-->
<mvc:exclude-mapping path="resources/**"/>
<mvc:exclude-mapping path="/**.ico"/>
<mvc:exclude-mapping path="/**.jpg"/>
<mvc:exclude-mapping path="/**.png"/>
<mvc:exclude-mapping path="/**.gif"/>
<mvc:exclude-mapping path="/**.js"/>
<mvc:exclude-mapping path="/**.css"/>
<mvc:exclude-mapping path="/**.jpge"/>
<bean class="fun.afterglow.restful.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
- 前置请求return:对URL进行前置检查,复合要求进行放行,不符合要求,在拦截器中进行处理返回响应
开发用户流量拦截器
- 需求:用户基础数据的采集,日志存储 logback.xml
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%thread] %d %level %logger{10} - %msg%n</pattern>
</encoder>
</appender>
<!--RollingFileAppender日滚动文件:生成按天生成的日志文件-->
<appender name="accessHistoryLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--TimeBasedRollingPolicy:按照时间开始滚动-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>e:/logs/history.%d.log</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>[%thread] %d %level %logger{10} - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="console"/>
</root>
<logger name="fun.afterglow.restful.interceptor.AccessHistoryInterceptor" level="INFO" additivity="false">
<appender-ref ref="accessHistoryLog"/>
</logger>
</configuration>
AccessHistoryInterceptor拦截器
//属于前置处理
public class AccessHistoryInterceptor implements HandlerInterceptor {
private Logger logger = LoggerFactory.getLogger(AccessHistoryInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
StringBuilder log = new StringBuilder();
//获取用户访问的IP
log.append(request.getRemoteAddr());
log.append("|");
//获取用户访问的URL
log.append(request.getRequestURL());
log.append("|");
//获取用户客户端
log.append(request.getHeader("user-agent"));
logger.info(log.toString());
return true;
}
}
===============================
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/js/**"/>
<bean class="fun.afterglow.restful.interceptor.AccessHistoryInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>