目录
一、Interceptor是什么?
二、实现步骤
1.引入依赖
2.实现HandlerInterceptor接口
3.applicationContext配置过滤地址
三、拦截器应用技巧
1.排除静态资源的访问
2.多个interceptor执行顺序
3.配置用户流量拦截器
1.引入日志logback依赖
2.在resources目录下创建logback.xml文件
3.创建拦截类的日志记录规则
4.在applicationContext.xml配置拦截器
四、SpringMVC处理流程
一、Interceptor是什么?
拦截器(Interceptor)用于对URL请求进行前置/后置过滤。
Interceptor与Filter用途相似,但实现方式不同。
Interceptor底层就是基于Spring AOP 面向切面编程实现
拦截器和过滤器它的作用是非常相似的,都是对于请求的拦截,但是他们底层的实现逻辑是不同的,interceptor是SpringMVC的标准组件,interceptor对象在被创建了以后是运行在Spring IOC容器中的,而filter呢,它则是J2EE的标准组件,是J2EE的标准,作为filter是由不同的第三方容器厂商所实现的,所以他们两个虽然作用相似,但底层的实现逻辑是截然不同的。第3点是interceptor是对请求进行前置后置的过滤处理,那试想一下在我们以前学习spring的时候,还有什么样的组件是可以实现类似的功能呢?就是Spring 的AOP。 Interceptor底层最基本实现就是依赖于AOP的编程理念,与AOP非常相似。
二、实现步骤
1.引入依赖
代码如下(示例):
<repositories>
<repository>
<id>aliyun</id>
<name>aliyun</name>
<url>https://maven.aliyun.com/repository/public</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.9</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.9</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.9</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
2.实现HandlerInterceptor接口
在controller目录下创建interceptor.MyInterceptor类
public class MyInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println(request.getRequestURL() + "-准备执行");
// response.getWriter().print("[]");
return true; //false,会直接返回客户端 、true会送达给后面的拦截器或者控制器
}
//controller方法执行return后执行,即相应文本之前
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println(request.getRequestURL() + "-目标处理成功");
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println(request.getRequestURL() + "-响应内容已产生");
}
}
3.applicationContext配置过滤地址
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/restful/**"/>
<mvc:mapping path="/webapi/**"/>
<bean class="com.yygs.restful.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
三、拦截器应用技巧
1.排除静态资源的访问
拦截器不受静态资源不处理的配置的影响。即所有符合拦截器的URL都会被拦截,也就包括静态资源,那么需要排除静态资源:我们可以在webapp目录下创建resources目录,专门存放静态资源,然后过滤器设置排除resources这个目录内的所有资源。
<mvc:interceptors>
<mvc:interceptor>
<mvc:exclude-mapping path="/**.ico"/>
<mvc:exclude-mapping path="/**.jpg"/>
<mvc:exclude-mapping path="/**.gif"/>
<mvc:exclude-mapping path="/**.js"/>
<mvc:exclude-mapping path="/**.css"/>
<mvc:exclude-mapping path="/resources/**"/>
<bean class="com.yygs.restful.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
那么修改文件存放位置之后,前端访问静态资源的URL也要发生变化:
<script src="/resources/js/jquery-3.3.1.min.js"></script>
我们也可以对Controller下的URL经行拦截:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/restful/**"/>
<mvc:mapping path="/webapi/**"/>
<mvc:exclude-mapping path="/resources/**"/>
<bean class="com.yygs.restful.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
2.多个interceptor执行顺序
前后拦截器顺序跟书写顺序有关。
如果前面的拦截器中断了,return false,那么后面的拦截器不会执行,直接返回结果。
3.配置用户流量拦截器
使用日志来保存访问记录信息
1.引入日志logback依赖
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
2.在resources目录下创建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">
<!--滚动策略:按照时间-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志保存位置,%d:日期-->
<fileNamePattern>d:/logs/history.%d.log</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>[%thread] %d %level %logger{10} - %msg%n</pattern>
</encoder>
</appender>
<!--最低允许输出debug级别的日志-->
<root level="debug">
<!--引用上面的name="console"-->
<appender-ref ref="console"/>
</root>
<!--使用什么类描述的规则进行日志记录-->
<logger name="com.yygs.restful.interceptor.AccessHistoryInterceptor"
level="INFO" additivity="false">
<!--additivity如果为true,也会在控制台输出,false只会在文件中输出-->
<appender-ref ref="accessHistoryLog"/>
</logger>
</configuration>
3.创建拦截类的日志记录规则
public class AccessHistoryInterceptor implements HandlerInterceptor {
private Logger logger = LoggerFactory.getLogger(AccessHistoryInterceptor.class);
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
StringBuilder log = new StringBuilder();
log.append(request.getRemoteAddr());
log.append("|");
log.append(request.getRequestURL());
log.append("|");
log.append(request.getHeader("user-agent"));
logger.info(log.toString());
return true;
}
}
4.在applicationContext.xml配置拦截器
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/resources/**"/>
<bean class="com.yygs.restful.interceptor.AccessHistoryInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
四、SpringMVC处理流程