Mock11-拦截器服务实现(二)事半功倍的WebMvcConfigurer

2023-10-21 19:45:20 浏览数 (1)

本文将介绍 WebMvcConfigurer其类及其常用方法,并提供代码示例作为一个扩展学习,当然如果仅对于本项目只需要了解如何配置拦截就行。

类和方法介绍

WebMvcConfigurer 接口是 Spring MVC 中的一个关键接口,它允许我们通过实现该接口来自定义和配置 Spring MVC 的行为。它提供了丰富的方法,用于添加拦截器、配置视图解析器、处理静态资源等。

以下介绍几个常用方法:

配置视图解析器

WebMvcConfigurer 中的 configureViewResolvers() 方法允许我们配置视图解析器,以下是一个示例代码:

代码语言:javascript复制
@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.viewResolver((request, response, handler) -> {
            if (request.getServletPath().startsWith("/app/")) {
                return new InternalResourceView("/static/antdapp/index.html");
            }
            return null;
        });
    }
}

上述代码片段将请求的 Servlet 路径以/app/开头的情况下,将其路由到 Vue.js 应用的 index.html 页面。对于其他类型的视图解析器,我们不需要进行配置。

配置静态资源处理

使用 addResourceHandlers() 方法可以配置处理静态资源的路径和缓存策略,以下是一个示例代码:

代码语言:javascript复制
@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**")    // 指定了映射的资源路径,即当请求以/static/开头时,将会触发静态资源处理。
                .addResourceLocations("classpath:/static/")  // 指定了静态资源的位置。此处表示静态资源被放置在 classpath:/static/目录下,即资源将从项目的 src/main/resources/static/目录中获取
                .setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS));  // 设置了缓存控制。此处缓存策略表示源将被缓存一年,主要目的为提高性能和减少网络请求。
    }
}

上述代码片段配置了一个静态资源处理器,当请求以/static/开头时,会从 classpath:/static/目录下查找对应的静态资源,并应用缓存控制策略。

配置拦截器

通过 addInterceptors()方法,我们可以添加拦截器并设置拦截路径和排除路径,以下是一个示例代码:

代码语言:javascript复制
@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor())  // 建了一个拦截器对象MyInterceptor的实例,并添加到拦截器注册表中
                .addPathPatterns("/**")  // 需要拦截的请求路径。此行使用了/**,表示拦截所有请求
                .excludePathPatterns("/public/**"); // 指定了需要排除(不拦截)的请求路径。这行我们排除了以/public/开头的请求,这意味着这些请求将不会被拦截。
    }

这段代码表示拦截了所有请求(除了以/public/开头的请求)。在拦截器实现中,您可以添加自定义的逻辑来处理请求前、请求后的操作,例如身份验证、日志记录等。

如上一节 HandlerInterceptor 讲解中,主要用到的就是此配置。

配置消息转换器

configureMessageConverters()方法允许我们配置消息转换器,以下是一个示例代码:

代码语言:javascript复制
@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(new MappingJackson2HttpMessageConverter());
    }
}

通过上述配置,我们添加了一个MappingJackson2HttpMessageConverter消息转换器,用于处理JSON格式的数据。该转换器将Java对象转换为JSON字符串,并将其作为响应的内容返回。

在实际应用中,您可以根据需要添加其他类型的消息转换器,例如处理XML、处理自定义的数据格式等。通过添加自定义的消息转换器,您可以灵活地处理不同类型的数据,并确保适当的数据转换和序列化。

配置跨域资源共享(CORS)

使用 addCorsMappings()方法可以配置 CORS 支持,以下是一个示例代码:

代码语言:javascript复制
@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")  // 需要进行CORS配置的请求路径模式,此行表示对以/api/开头的请求进行CORS配置
                .allowedOrigins("http://example.com")  // 指定了允许访问该API的源(域)
                .allowedMethods("GET", "POST")  // 允许的请求方法
                .allowedHeaders("header1", "header2")  // 允许的请求头部信息
                .exposedHeaders("header3")  // 允许暴露给客户端的响应头部信息
                .allowCredentials(true)  // 设置是否允许发送凭证信息(例如,使用Cookie进行跨域请求)。
                .maxAge(3600);  // 置预检请求的缓存时间,以减少预检请求的频率。
    }
}

通过上述配置,我们为/api/路径下的请求添加了CORS配置,限制了允许访问的源、请求方法、请求头部信息,并设置了允许的响应头部信息、是否允许发送凭证信息以及预检请求的缓存时间。在实际应用中,可以根据需求进行更详细的CORS配置,以满足您的特定跨域访问需求。

WebMvcConfigurer还提供了其他常用的方法,例如配置内容裁剪策略、路径匹配和类型匹配、异步请求处理、默认 Servlet 处理等。

Mock服务中的应用

在了解了上述一系列的配置后,对于我们Mock项目可以采用两种方案:

方案一:独立项目服务部署,对所有请求拦截

此方案的好处是可以分离后台服务和网关服务,迭代升级独立更新部署互不影响,其中对于有mock有性能需求的可以进行独立的扩展,在本项目源码中就是采用的此方案,这里再回顾下配置。

代码语言:javascript复制
// 正则匹配所有路径请求
public void addInterceptors(InterceptorRegistry registry){
    registry.addInterceptor(new QMockInterceptor()).addPathPatterns("/**");
}

方案二:实现和部署在一个后端服务中,排除特殊的自定义前缀后剩余拦截

此方案的维护部署上更为简单,也升服务资源,适用于简单需求的Mock服务。在之前公司实际落地是采用的此方案。

配置的示例代码如下:

代码语言:javascript复制
public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(mockInterceptor()).excludePathPatterns("/index.html","/static/**","/eqa/**");
    }

这里主要是用到了 excludePathPatterns 进行定向排除。因之前将前端静态文件也一通打包部署,所以这里排除内容包含了 前端首页静态文件夹前端转发统一前缀。也就是说在对后端服务进行请求的时候这些内容是不被拦截的。

至此,我们将Mock实现两个核心类讲完了,后续我们就要以GET和POST两最常用方法请求进行实现Mock拦截匹配服务。

前文导读

  • Mock10-拦截器服务实现(一)探索HandlerInterceptor
  • Mock09-项目管理(五)搜索、删除和Table优化
  • Mock08-项目管理(四)下篇:自定义Component组件
  • Mock08-项目管理(四)上篇:编辑功能实现

0 人点赞