W
e
l
c
o
m
e
: )

Spring MVC拦截器

Interceptor

拦截器(Interceptor)用于对URL请求进行前置/后置过滤

Interceptor与Filter用途相似,但实现方式不同

Interceptor底层基于Spring AOP面向切面编程实现

拦截器开发流程

  1. Maven依赖servlet-api
  2. 实现HandlerInterceptor接口
  3. applicationContext配置过滤地址

HandlerInterceptor

preHandle - 前置执行处理

postHandle - 目标资源已经被SpringMVC框架处理:

afterCompletion - 响应文本以产生

1.引入依赖

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>

2.实现HandlerInterceptor接口

public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println(request.getRequestURL() + "前置处理已完成");
        return true; //如果为true会送达给后面的拦截器,fakse当前请求会被阻止直接返回给客户端
    }

    @Override
    //目标资源被处理成功,但是没有产生相应文本之前
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println(request.getRequestURL() + "目标处理成功");
    }

    @Override
    //当目标响应文本产生以后
    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="/**"/>
        <!--对URL进行处理-->
        <bean class="com.huazll.restful.interceptor.MyInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

Interceptor使用技巧

<mvc:interceptors>
    <mvc:interceptor>
        <!--对哪些地址进行拦截-->
        <mvc:mapping path="/**"/>
        <!--只对前缀为/restful的RRL进行拦截-->
        <mvc:mapping path="/restful/**"/>
        <!--exclude-mapping:过滤以下URL文件-->
        <mvc:exclude-mapping path="/**.js"/>
        <mvc:exclude-mapping path="/**.css"/>
        <!--只过滤前缀为/resources/...的RUL-->
        <mvc:exclude-mapping path="/resources/**"/>
        <!--对URL进行处理-->
        <bean class="com.huazll.restful.interceptor.MyInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

执行顺序

image-20220818184305638

Filter和Interceptor的区别

  1. Filter接口在javax.Servlet包下面。Interceptor定义在org.Springframework.web.Servlet中
  2. Filter基于Filter接口中的doFilter回调函数,时Servlet容器支持的;而Interceptor基于Java本身的反射机制(AOP思想),时Spring框架支持的
  3. Filter是依赖于Servlet容器的,没有Servlet容器就无法回调doFilter方法,而Interceptor与Servlet无关;
  4. Filter的过滤范围比Interceptor大,Filter除了过滤请求外通过通配符可以保护页面、图片、文件等,而Interceptor智能过滤请求,只对请求起作用,在请求之前开始,在请求完成后结束(如被拦截,不执行请求)。
  5. Filter的过滤一般在加载的时候在init()方法声明,而Inteceptor可以通过在xml生命是guest请求还是user请求,来辨别是否过滤。
  6. Interceptor可以访问请求上下文、值栈里的对象,而Filter不能。
  7. 在请求的生命周期中,拦截器可以被多次调用,而过滤器智能在容器初始化被调用一次。

开发用户流量拦截器

<?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>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>
    <!--打印当前类的运行日志,不向控制台打印。使用accessHistoryLog进行记录-->
    <logger name="com.huazll.restful.interceptor.AccessHistoryInterceptor" level="INFO" additivity="false">
        <appender-ref ref="accessHistoryLog"/>
    </logger>
</configuration>
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;
    }
}

SpringMVC处理流程

Handler:处理器,在计算机中也叫句柄。可以认为是控制器(Controller)或拦截器(Interceptor)

执行链:

image-20220819001613892

浏览器发送URL请求经过DispacherServlet拦截处理,交由SpringMVC进行处理。查找Handler并返回执行链,将执行链返回给DispacherServlet再向HandlerAdapter,根据类型执行对应方法,执行Controller的方法返会ModelAndView被HandlerAdapter接收并返回给DispacherServlet。DispacherServlet会判断ModelAndView被哪个模板引擎处理,根据View中的配置返回对应的视图解析器返回给DispacherServlet,根据ModelAndView中的数据组成HTML片段返回给浏览器

image-20220819002913318

posted @ 2022-12-02 19:23  与你一起看星辰  阅读(28)  评论(0)    收藏  举报