• 后端——框架——视图层框架——spring mvc——过滤器 & 拦截器


    1、拦截器

      拦截器是由Spring提供,类似Filter功能的类,它可以拦截DispatcherServlet分发的请求。

    与Filter不同之处在于,Filter适用于所有Servlet,而拦截器(Interceptor)只适用于DispatcherServlet分发的请求。当同时有Filter,Interceptor存在的情况下,请求的执行链如下:

    Filter chain---->DispatcherServlet的doService方法------>获取HandlerExecutionChain,执行HandlerInterceptor chain----->Controller中的handler方法。

    使用拦截器有两个步骤:

    1. 自定义HandlerInterceptor接口的实现类,例如TestInterceptor。
    2. 注册HandlerInterceptor,注册的方式有两种,代码方式,在配置文件中配置。

    编写HandlerInterceptor接口的实现类较为简单。只做练习的话,打印几条输出语句即可。

    HandlerInterceptor有三个方法,

    1. preHandle:在Controller的handler方法之前执行,返回true时继续执行下一个Handler,若是最后一个Handler,则执行Controller中的方法。返回false时,表示请求终止,不会有任何后续。
    2. postHandle:在Controller的handler方法之后执行,当响应类型为数据流时,即直接向response对象的输出流写入数据时,例如调用response.getWriter.append方法,标注有@ResponseBody的handler。此方法不会执行。
    3. afterCompletion:在请求结束,响应关闭,线程资源被回收之后运行。

      注册有两种方式,

    代码方式,示例如下:

    public void addInterceptors(InterceptorRegistry registry) {
    	// 调用InterceptorRegistry的addInterceptor方法
    	// 拦截所有的请求,除login
    	registry.addInterceptor(new TestInterceptor()).addPathPatterns("/**").excludePathPatterns("/login");
    }
    

      XML配置文件方式,示例如下:

    <mvc:interceptor>
    	<mvc:mapping path="/**"/>
    	<mvc:exclude-mapping path="/login"/>
    	<bean class="interceptor.TestInterceptor"/>
    </mvc:interceptor>
    

    2、过滤器

      本篇介绍mvc内置的过滤器。使用频率很低。

    2.1   FormContent

      引用原著中的定义:

      the spring-web module provides FormContentFilter to intercept HTTP PUT, PATCH, and DELETE requests with a content type of application/x-www-form-urlencoded, read the from data from the body of request, and wrap the ServletRequest to make the form data available through the ServletRequest.getParameter*() family of methods

    默认情况下,ServletRequest的getParameter*方法只能获取get和post请求类型中的参数。

    添加FormContentFilter,它会适用于所有类型的请求。

    使用步骤如下:

    配置FormContentFilter拦截器拦截DispatcherSerlvet。代码如下:

    // 添加过滤器
    FilterRegistration.Dynamic filterRegistration = servletContext.addFilter("formContentFilter", new FormContentFilter());
    // 配置请求的分发类型
    EnumSet<DispatcherType> dispatchers = EnumSet.of(DispatcherType.REQUEST, DispatcherType.ASYNC, DispatcherType.FORWARD,DispatcherType.INCLUDE);
    filterRegistration.addMappingForServletNames(dispatchers, true, "dispatcherServlet");
    

      编写任意的PUT,DELETE请求验证即可

    2.2 ForwardedHeader

      引用原著中的定义:

    ForwardedHeaderFilter is a Servlet filter that modifies the host, port, and scheme of the request, based on Forwarded headers, and then removes those headers

    ForwardedHeaderFilter可以修改请求头中关于主机,端口,协议等信息。请求头中记录这些信息的属性有:

    static {
    	FORWARDED_HEADER_NAMES.add("Forwarded");
    	FORWARDED_HEADER_NAMES.add("X-Forwarded-Host");
    	FORWARDED_HEADER_NAMES.add("X-Forwarded-Port");
    	FORWARDED_HEADER_NAMES.add("X-Forwarded-Proto");
    	FORWARDED_HEADER_NAMES.add("X-Forwarded-Prefix");
    	FORWARDED_HEADER_NAMES.add("X-Forwarded-Ssl");
    }
    

      略。

    2.3   ShallowEtagHeader

    ShallowEtagHeaderFilter会根据响应的内容生成”shallow etag”,再次请求时,会将该值作为请求头中If-None-Match属性值,并与”shallow etag”的值进行比较,若二者相等返回304, Not Modified。相当于给请求添加缓存的功能。

    使用步骤如下:

    1. 第一步,创建ShallowEtagHeaderFilter对象,
    2. 第二步,注册ShallowEtagHeaderFilter,拦截DispactherServlet,或者是URL地址都可以。
    // ShallowEtagHeaderFilter
    ShallowEtagHeaderFilter eTagHeader = new ShallowEtagHeaderFilter();
    eTagHeader.setWriteWeakETag(true);
    FilterRegistration.Dynamic shadowETagFilter = servletContext.addFilter("shadowETagFilter", eTagHeader);
    shadowETagFilter.addMappingForServletNames(dispatchers, true, "dispatcherServlet");
    

      3. 第三步,验证。第一次请求时请求头中无If-None-Match属性,响应码为200。再次请求时,请求头中有If-None-Match属性值,浏览器中的响应码为304

    // 调用request.getHeader方法
    if-none-match: W/"0d2d08b5003a04494f5de83f30a514e17"
    // 浏览器中查看
    Status Code: 304
    

    2.4  CorsFilter

      使用CorsFilter的步骤如下:

      第一步,配置过滤器。

    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("http://domain1.com");
    config.addAllowedHeader("*");
    config.addAllowedMethod("*");
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", config);
    CorsFilter filter = new CorsFilter(source);
    

      第二步,Servlet添加过滤器。在web.xml中配置也是相同的

    // 添加过滤器,filter为之前创建的CorsFilter
    FilterRegistration.Dynamic filterRegistration = servletContext.addFilter("crosFilter", filter);
    // 配置请求的分发类型
    EnumSet<DispatcherType> dispatchers = EnumSet.of(DispatcherType.REQUEST, DispatcherType.ASYNC, DispatcherType.FORWARD, DispatcherType.INCLUDE);
    // 过滤器拦截dispatcherServlet
    filterRegistration.addMappingForServletNames(dispatchers, true, "dispatcherServlet");
  • 相关阅读:
    Spring事务的一些基本知识(一)
    Redis管道
    Spring事务的一些基本知识(四)大事务的危害与优化
    登录页面测试点
    朋友圈点赞用例的设计点
    面向对象
    函数的重载
    构造代码块和静态代码块,构造函数的执行
    单例设计模式
    三分查找(2020icp南京F)
  • 原文地址:https://www.cnblogs.com/rain144576/p/14823841.html
Copyright © 2020-2023  润新知