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

相关推荐
niceffking2 分钟前
JVM HotSpot 虚拟机: 对象的创建, 内存布局和访问定位
java·jvm
菜鸟求带飞_5 分钟前
算法打卡:第十一章 图论part01
java·数据结构·算法
骆晨学长22 分钟前
基于springboot的智慧社区微信小程序
java·数据库·spring boot·后端·微信小程序·小程序
AskHarries27 分钟前
利用反射实现动态代理
java·后端·reflect
@月落28 分钟前
alibaba获得店铺的所有商品 API接口
java·大数据·数据库·人工智能·学习
bjzhang7529 分钟前
SpringBoot开发——整合SpringDoc实现在线接口文档
spring boot·springdoc
liuyang-neu33 分钟前
力扣 42.接雨水
java·算法·leetcode
z千鑫37 分钟前
【人工智能】如何利用AI轻松将java,c++等代码转换为Python语言?程序员必读
java·c++·人工智能·gpt·agent·ai编程·ai工具
Flying_Fish_roe1 小时前
Spring Boot-Session管理问题
java·spring boot·后端
赚钱给孩子买茅台喝1 小时前
智能BI项目第四期
java·spring boot·spring cloud·aigc