SpringBoot - WebMvcConfigurer的作用是什么

WebMvcConfigurer是一个接口,用于配置全局的SpringMVC的相关属性,采用JAVABEAN的方式来代替传统的XML配置文件,提供了跨域设置、静态资源处理器、类型转化器、自定义拦截器、页面跳转等能力。
WebMvcConfigurer 在 Spring Boot 2.x 中官方建议使用该接口来实现自定义配置。所以,Spring Boot 2.x 中,自定义 SpringMVC 配置可以通过实现 WebMvcConfigurer 接口来完成。
源码说明

public interface WebMvcConfigurer {
    //  配置路径匹配规则
    default void configurePathMatch(PathMatchConfigurer configurer) { }

    // 内容协商
    default void configureContentNegotiation(ContentNegotiationConfigurer configurer) { }
    
    // 异步调用支持
    default void configureAsyncSupport(AsyncSupportConfigurer configurer) { }

    // 静态资源默认处理器
    default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { }

    // 格式化器, 可以把时间转化成你需要时区或者格式,还可以将对象A转换为对象B。
    default void addFormatters(FormatterRegistry registry) { }

    // 请求拦截器
    default void addInterceptors(InterceptorRegistry registry) { }

    // 静态资源映射器
    default void addResourceHandlers(ResourceHandlerRegistry registry) { }

    // 跨域设置
    default void addCorsMappings(CorsRegistry registry) { }

    // 视图控制器
    default void addViewControllers(ViewControllerRegistry registry) { }

    // 视图解析器
    default void configureViewResolvers(ViewResolverRegistry registry) { }

    // 参数处理器
    default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { }

    // 返回值处理器
    default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) { }

    // 信息转化器
    default void configureMessageConverters(List<HttpMessageConverter<?>> converters) { }

    // 信息转化器扩展
    default void extendMessageConverters(List<HttpMessageConverter<?>> converters) { }

    // 异常处理器
    default void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) { }

    // 异常处理器扩展
    default void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) { }

    @Nullable
    default Validator getValidator() {
        return null;
    }

    @Nullable
    default MessageCodesResolver getMessageCodesResolver() {
        return null;
    }
}

   

常用示例
① 配置路径匹配规则

@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
    // 是否使用尾斜杠匹配, 默认为TRUE。TRUE, 表示"/hello"和"/hello/"都能匹配。
    configurer.setUseTrailingSlashMatch(false);
 
    // 为所有的接口添加统一前缀。如果的URL为: "/hello", 则转换为: "/api/hello"
    configurer.addPathPrefix("api", c -> c.isAnnotationPresent(RestController.class));
 
    // UrlPathHelper是一个处理URL地址的帮助类, 自带了一些优化URL的方法;
    // 如:getSanitizedPath,就是将"//"自动转换为"/", 所以当输入为"//"也是没有问题的,
    UrlPathHelper urlPathHelper = new UrlPathHelper();
    configurer.setUrlPathHelper(urlPathHelper);
}

② 配置静态资源映射器

用于自定义静态资源的映射目录。

// addResourceHandler:用于设置对外暴露的访问路径
// addResourceLocations:用于映射内部文件放置的目录,需要以“/”结尾

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    /** 本地文件上传路径 */
    // 对外暴露的访问路径
    registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**")
    // 映射内部文件放置的目录,以“/”结尾
            .addResourceLocations("file:" + ServicexConfig.getProfile() + "/");

    /** swagger配置 */
    registry.addResourceHandler("/swagger-ui/**")
            .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");
}

③ 配置请求拦截器

可以设置多个拦截器,如对特定的URL设定处理规则、打印处理用户请求耗费的时间、定义防止重复提交等功能。

@Override
public void addInterceptors(InterceptorRegistry registry) {
    // 增加一个拦截器,对请求做一些自定义处理
    registry.addInterceptor(new HandlerInterceptor() {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            Object user = request.getSession().getAttribute("loginUser");
            if (user == null) {   //未登陆,返回登陆页面
                request.setAttribute("msg", "没有权限请先登陆");
                request.getRequestDispatcher("/index.html").forward(request, response);
                return false;
            } else {  //已登陆,放行请求
                return true;
            }
        }
    })
    // 设置拦截器的过滤路径规则:只拦截/admin/形式的请求
    .addPathPatterns("/admin/**")
    // 设置不需要拦截的过滤规则:不拦截/admin/login请求
    .excludePathPatterns("/admin/login");
}

④ 跨域设置

方法一:
@Override
public void addCorsMappings(CorsRegistry registry) {
    // 设置允许跨域的路径
    registry.addMapping("/**")
            // 设置允许跨域请求的域名
            .allowedOrigins("*")
            // 是否允许证书
            .allowCredentials(true)
            // 设置允许的方法
            .allowedMethods("GET", "POST", "DELETE", "PUT")
            // 设置允许的header属性
            .allowedHeaders("*")
            // 跨域允许时间
            .maxAge(3600);
}

方法二:
/**
 * 跨域配置
 */
@Bean
public CorsFilter corsFilter() {
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    // 设置访问源地址
    config.addAllowedOriginPattern("*");
    // 设置访问源请求头
    config.addAllowedHeader("*");
    // 设置访问源请求方法
    config.addAllowedMethod("*");
    // 有效期 1800秒
    config.setMaxAge(1800L);
    // 添加映射路径,拦截一切请求
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", config);
    // 返回新的CorsFilter
    return new CorsFilter(source);
}

⑤ 视图控制器

用于将请求的URL进行处理。

@Override
public void addViewControllers(ViewControllerRegistry registry) {
    // 如果请求为:/admin,则重定向到/login
    registry.addRedirectViewController("/admin", "/login");
    // 如果请求为:/admin/delete,则返回500状态
    registry.addStatusController("/admin/delete", HttpStatus.INTERNAL_SERVER_ERROR);
    // 如果请求URL为:/hello,则直接跳转到hello页面
    registry.addViewController("/hello").setViewName("hello");
}

⑥ 内容协商

用于将一个URL直接跳转到页面。

@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    // 自定义策略
    configurer.favorPathExtension(true)// 是否通过请求Url的扩展名来决定mediaType,默认true
            .ignoreAcceptHeader(true)// 不检查Accept请求头
            .parameterName("mediaType")
            .defaultContentType(MediaType.TEXT_HTML)// 设置默认的MediaType
            .mediaType("html", MediaType.TEXT_HTML)// 请求以.html结尾的会被当成MediaType.TEXT_HTML
            .mediaType("json", MediaType.APPLICATION_JSON)// 请求以.json结尾的会被当成MediaType.APPLICATION_JSON
            .mediaType("xml", MediaType.APPLICATION_ATOM_XML);// 请求以.xml结尾的会被当成MediaType.APPLICATION_ATOM_XML
}

⑦ 信息转化器扩展

自定义FASTJSON为JSON消息的转换器,完成的功能如下:
1、请求返回体使用FASTJSON来序列化;
2、配置如果字段类型为Date,输出为"yyyy-MM-dd HH:mm:ss"格式;
3、配置允许输出值为null的字段;
4、配置字符类型字段,如果为null,输出为"",而非null;
5、配置把Long类型的数据序列化成JSON后传给前端,解决前端可能会出现精度丢失的情况。

@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
    //1、首先定义一个convert消息转换对象
    FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();

    //2、定义支持的mediaType类型,处理中文乱码的相关问题
    List<MediaType> mediaTypes = new ArrayList<>();
    mediaTypes.add(MediaType.APPLICATION_JSON);      // 返回JSON格式
    mediaTypes.add(MediaType.APPLICATION_JSON_UTF8); // 处理输出中文乱码
    mediaTypes.add(MediaType.TEXT_HTML);
    mediaTypes.add(new MediaType("application", "xml"));
    mediaTypes.add(new MediaType("text", "xml"));
    mediaTypes.add(new MediaType("application", "*+xml"));
    mediaTypes.add(MediaType.ALL);
    converter.setSupportedMediaTypes(mediaTypes);

    //3. 创建配置类
    FastJsonConfig fastJsonConfig = new FastJsonConfig();
    fastJsonConfig.setCharset(Charset.forName("UTF-8")); // 全局编码
    fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss"); // 全局时间格式化

    //4. 格式化返回内容
    SerializerFeature[] serializerFeatures = new SerializerFeature[]{
            SerializerFeature.PrettyFormat,             // 格式化
            SerializerFeature.WriteMapNullValue,        // 输出空值
            SerializerFeature.WriteNullListAsEmpty,     // List字段如果为null,输出为[],而非null
            SerializerFeature.WriteDateUseDateFormat,   // 日期格式化
            SerializerFeature.WriteNullStringAsEmpty,   // 字符类型字段如果为null,输出为"",而非null
            SerializerFeature.WriteNullBooleanAsFalse,  // Boolean字段如果为null,输出为false,而非null
            SerializerFeature.DisableCircularReferenceDetect, //消除对同一对象循环引用的问题,默认为false(如果不配置有可能会进入死循环)
            SerializerFeature.WriteNullNumberAsZero     //数字类型如果为null,输出为0,而非null
    };
    fastJsonConfig.setSerializerFeatures(serializerFeatures);

    //5. 配置Java类型对应的序列化类,序列换成json时, 将所有的long变成string,解决Long转json精度丢失的问题,因为js中得数字类型不能包含所有的java long值
    SerializeConfig serializeConfig = SerializeConfig.globalInstance;
    serializeConfig.put(BigInteger.class, ToStringSerializer.instance);
    serializeConfig.put(Long.class, ToStringSerializer.instance);
    serializeConfig.put(Long.TYPE, ToStringSerializer.instance);
    fastJsonConfig.setSerializeConfig(serializeConfig);

    converter.setFastJsonConfig(fastJsonConfig);
    converters.add(0,converter);
}

 
 
 

其他方式

A. WebMvcConfigurerAdapter
B. WebMvcConfigurationSupport
C. @EnableWebMvc
A. WebMvcConfigurerAdapter

在 Spring Boot 1.x 中我们自定义 SpringMVC 时继承的一个抽象类,这个抽象类本身是实现了 WebMvcConfigurer 接口。从 Spring5 开始,官方建议直接实现 WebMvcConfigurer 接口,而不是继承 WebMvcConfigurerAdapter。
B. WebMvcConfigurationSupport

在纯 Java 配置的 SSM 环境中,如果我们要自定义 SpringMVC 配置,有两种办法:
第一种就是直接继承自 WebMvcConfigurationSupport 来完成 SpringMVC 配置;
还有一种方案就是实现 WebMvcConfigurer 接口来完成自定义 SpringMVC 配置,如果使用第二种方式,则需要给 SpringMVC 的配置类上额外添加 @EnableWebMvc 注解,表示启用 WebMvcConfigurationSupport,这样配置才会生效。
C. @EnableWebMvc

如果在 Spring Boot 中使用了 @EnableWebMvc 注解,就会导致 Spring Boot 中默认的 SpringMVC 自动化配置失效,所以不建议使用该方式。
————————————————
版权声明:本文为CSDN博主「cloneme01」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/goodjava2007/article/details/126132375

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/8152.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

疲劳驾驶检测和识别3:Android实现疲劳驾驶检测和识别(含源码,可实时检测)

疲劳驾驶检测和识别3&#xff1a;Android实现疲劳驾驶检测和识别(含源码&#xff0c;可实时检测) 目录 疲劳驾驶检测和识别3&#xff1a;Android实现疲劳驾驶检测和识别(含源码&#xff0c;可实时检测) 1.疲劳驾驶检测和识别方法 2.人脸检测方法 3.疲劳驾驶检测和识别模型…

《人工智能安全》课程总体结构

1 课程内容 人工智能安全观&#xff1a;人工智能安全问题、安全属性、技术体系等基本问题进行了归纳整理。人工智能安全的主要数据处理方法&#xff0c;即非平衡数据分类、噪声数据处理和小样本学习。人工智能技术赋能网络空间安全攻击与防御&#xff1a;三个典型实例及攻击图…

QT在线安装程序下载链接

最新版本 Download Qt OSS: Get Qt Online Installer 安装时&#xff0c;可以选择不同的QT SDK版本。 源码下载版本 https://download.qt.io/archive/qt/

【Oracle系列】- Oracle数据迁移

【Oracle系列】- Oracle数据迁移 文章目录 【Oracle系列】- Oracle数据迁移一、概述二、数据迁移方案三、模拟迁移方案四、迁移步骤五、迁移方案及其实施细则5.1 exp/imp逻辑备份与恢复5.2 Storage存储迁移5.3 利用data guard迁移 一、概述 最近在做公司软件系统盘点时&#x…

Android中保持屏幕常亮的三种使用方法

目录 一、设置Flag 二、使用View类中的属性方法 1、Xml布局中设置&#xff1a; 2、功能代码中设置&#xff1a; 三、Wakelock 锁定机制 1、简介 2、作用 3、分类标志 4、使用方法 &#xff08;1&#xff09;在AndroidManifest.xml中设置权限 &#xff08;2&#xff0…

Vue异步更新、$nextTick

需求&#xff1a;编辑标题, 编辑框自动聚焦 1. 点击编辑&#xff0c;显示编辑框 2. 让编辑框&#xff0c; 立刻获取焦点 this. isShowEdit true // 显示输入框 this . $refs . inp . focus () // 获取焦点 问题&#xff1a;"显示之后"&#xff0c;立刻获…

24 鼠标常用事件

鼠标进入&#xff1a;enterEvent鼠标离开&#xff1a;leaveEvent鼠标按下&#xff1a;mousePressEvent鼠标释放&#xff1a;mouseRelaseEvent鼠标移动&#xff1a;mouseMoveEvent 提升为自定义控件MyLabel 代码&#xff1a; //mylabel.h #ifndef MYLABEL_H #define MYLABEL_H#…

易班开放应用授权重定向,出现跨域的解决方案

问题描述 今天开发H5网站需要接入易班&#xff0c;经过易班授权然后重定向&#xff08;code: 302&#xff09;&#xff0c;使用axios发请求&#xff0c;但是前后端均配置跨域的情况下&#xff0c;不管怎么弄都是一直跨域 但是我们看network&#xff0c;network中对应请求的res…

微服务初始

今天准备开始学习微服务&#xff0c;使用微服务肯定是因为他有好处。 首先了解到的三种架构&#xff0c;传统单体&#xff0c;集群架构&#xff0c;微服务架构 单体架构 有单点问题&#xff0c;如果宕机所有的服务都不可用所有业务的功能模块都聚集在一起&#xff0c;如果代…

tinkerCAD案例:9. Saw Shaped Wrench 锯形扳手

tinkerCAD案例&#xff1a;9. Saw Shaped Wrench 锯形扳手 ln this lesson you will learn how to create a cool saw shaped wrench. 在本课中&#xff0c;您将学习如何制作一个很酷的锯形扳手。 Start the lesson by dragging a polygon to the workplane. 通过将多边形拖动…

Windows实现端口转发(附配置过程图文详解)

文章目录 1. 前言2. 命令提示符3. 防火墙4. netsh 命令4.1 查看已有的转发规则4.2 新增转发规则4.3 删除转发规则 5. 图解汇总6. 欢迎纠正~ 1. 前言 利用Windows端口转发&#xff0c;实现本地设备 ⬅➡ 公网主机 ⬅➡ 远端服务器 2. 命令提示符 以管理员身份打开“命令提示…

python调用百度ai将图片识别为表格excel

python调用百度ai将图片识别为表格excel ocr ocr 百度ai官方文档&#xff1a;https://ai.baidu.com/ai-doc/OCR/Ik3h7y238 import requests import json import base64 import time文档&#xff1a;https://ai.baidu.com/ai-doc/OCR/Ik3h7y238 # 获取access_token def get_acc…

vue3+ts+element-plus 之使用node.js对接mysql进行表格数据展示

vue3tselement-plus axiosnode.jsmysql开发管理系统之表格展示 ✏️ 1. 新建一个node项目* 初始化node* 安装可能用到的依赖* 配置文件目录* 添加路由router1. 添加router.js文件&#xff0c;添加一个test目录2. 修改app.js ,引入router&#x1f4d2; 3. 启动并在浏览器打开 * …

【1++的C++初阶】之适配器

&#x1f44d;作者主页&#xff1a;进击的1 &#x1f929; 专栏链接&#xff1a;【1的C初阶】 文章目录 一&#xff0c;什么是适配器二&#xff0c;栈与队列模拟实现三&#xff0c;优先级队列四&#xff0c;reverse_iterator 一&#xff0c;什么是适配器 适配器作为STL的六大组…

哪些油封密封件可用于旋转轴?

哪些密封件可用于旋转轴?当考虑可用于有效密封旋转轴的各种选项时&#xff0c;就会出现这个问题。选择合适的密封件取决于几个因素&#xff0c;包括应用的性质、操作条件和所需的密封性能水平。 一种常用的旋转轴密封件是唇形密封件&#xff0c;也称为径向轴密封件。唇形密封…

PHP类与对象 (基础)

文章目录 PHP之 类与对象 &#xff08;基础&#xff09;简介类的概念以及特点对象的概念以及特点类与对象的关系类与对象的意义 PHP中类的基本概念PHP中类常用的操作符类属性和类方法PHP中类的分类class声明类的封装类的属性类的公共方法&#xff08;函数&#xff09;构造函数析…

【爬虫逆向案例】某道翻译js逆向—— sign解密

声明&#xff1a;本文只作学习研究&#xff0c;禁止用于非法用途&#xff0c;否则后果自负&#xff0c;如有侵权&#xff0c;请告知删除&#xff0c;谢谢&#xff01; 【爬虫逆向案例】某道翻译js逆向—— sign解密 1、前言2、步骤3、源码4、号外 1、前言 相信各位小伙伴在写…

SAMStable-Diffusion集成进化!分割、生成一切!AI绘画新玩法

自SAM「分割一切」模型推出之后&#xff0c;二创潮就开始了&#xff0c;有想法有行动&#xff01;飞桨AI Studio开发者会唱歌的炼丹师就创作出SAM进化版&#xff0c;将SAM、Stable Diffusion集成&#xff0c;实现「分割」、「生成」能力二合一&#xff0c;并部署为应用&#xf…

A General framework for Prompt

你已经知道了 Prompt 可以具有一些通用的结构&#xff0c;比如一个简单的Prompt 结构: 能否帮我为我的课程 TAI自动化&#xff0c;设计一套数字营销策略? Action 我们的目标是激发目标受众一一那些希望利用人工智能简化工作流的人们的兴趣&#xff0c;并提高课程的知名度。 G…

JVM - 运行时数据区域

文章目录 程序计数器栈堆方法区知识延申 -- 字符串常量池 程序计数器 并发情况下&#xff0c;会发生线程之间的上下文切换&#xff0c;当 线程1 的CPU时间片用完后&#xff0c;需要程序计数器记录 线程1 的下一条JVM指令的地址&#xff0c;等下一次 线程1 继续运行的时&#x…