一.拦截器-Interceptor
1. 概念
拦截器用于对URL请求进行前置/后置过滤
Interceptor与Filter用途相似,但实现方式不同
Interceptor底层就是基于SpringAOP面向切面编程实现
2. 拦截器开发流程
Maven依赖servlet-api
实现HandlerInterceptor
applicationContext配置过滤地址
3. HandlerInterceptor接口
preHandle-前置执行处理
postHandle - 目标资源已被Spring MVC框架处理
afterCompletion - 响应文本已经产生
4. 具体开发流程
第一步:在pom.xml文件中引入javax.servlet
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
provided:含义是只有在开发,编译才会引用,在打包最终使用的时候,这个jar会被排除在外
第二步:所有拦截需要实现HandlerInterceptor
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println(request.getRequestURI()+"准备执行");
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println(request.getRequestURI()+"目标处理完成");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println(request.getRequestURI()+"响应内容已产生");
}
}
preHandle:发生在请求前
postHandle发生在请求后
afterCompletion:已经产生响应内容
第三步:在xml中对所有拦截器进行配置
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.imooc.restful.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
<mvc:mapping path=“/**”/>配置拦截器拦截范围
用自定义拦截器进行拦截
5. 使用技巧
资源过滤与排除
静态资源的排除
<mvc:exclude-mapping path=“/.xxx"/>
<mvc:exclude-mapping path="/resources/”/>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/restful/**"/>
<mvc:mapping path="/webapi/**"/>
<mvc:exclude-mapping path="/**.ioc"/>
<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.imooc.restful.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/restful/**"/>
<mvc:mapping path="/webapi/**"/>
<mvc:exclude-mapping path="/**.ioc"/>
<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.imooc.restful.interceptor.MyInterceptor1"/>
</mvc:interceptor>
</mvc:interceptors>
多Interceptor执行顺序
在MyInterceptor自定义拦截中preHandle返回的false会阻断,这里return就是拦截器开关
response.getWriter().print(“[]”);如果对某一个url前置检查,返回响应,将错误信息返回给前端
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println(request.getRequestURI()+"准备执行");
response.getWriter().print("[]");
return true;
}
二.开发“用户流量”拦截器
在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>
<!--日滚动文件-->
<appender name="accessHistoryLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--滚动策略,按时间滚动-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--文件保存地址-->
<fileNamePattern>d:/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="com.imooc.restful.interceptor.AccessHistoryInterceptor"
level="INFO" additivity="false">
<!--这里additivity是true就会网控制台输出,false就会往RollingFileAppender输出-->
<appender-ref ref="accessHistoryLog"/>
</logger>
</configuration>
[%thread]:线程的名字
%d:产生日志的时间
%level:日志的级别
%logger{10}:由那个类产生的日志,如果类名太长,需要相应的压缩,10对应了包名最大的长度
%msg%n
RollingFileAppender:生成每一天一个日志文件,防止所有日志都记录在大文件中,以天为单位单独写的,如果想要那一天的文件就找到当天的文件就行
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
在application中配置
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:mapping path="/resources/**"/>
<bean class="com.imooc.restful.interceptor.AccessHistoryInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
在AccessHistoryInterceptor中来获取相关信息并从日志文件中输出
private Logger logger = LoggerFactory.getLogger(AccessHistoryInterceptor.class);
@Override
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;
}
三.SpringMVC处理流程