feat(webmvc): Add API suffix configuration and optimize version mapping - Rename VersionProperties to WebMvcVersionProperties

- Add the apiSuffix property to configure the API suffix
- Update VersionAutoConfiguration and ApiVersionRequestMappingHandlerMapping to support the new configuration
- Optimized the version mapping logic to support the combination of prefix and suffix
This commit is contained in:
gewuyou 2025-05-16 12:11:12 +08:00
parent 0ca32efc02
commit 88f016dad2
3 changed files with 43 additions and 15 deletions

View File

@ -11,8 +11,8 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
* @author gewuyou * @author gewuyou
* @since 2025-05-02 11:52:24 * @since 2025-05-02 11:52:24
*/ */
@ConfigurationProperties(prefix = "forgeboot.version") @ConfigurationProperties(prefix = "forgeboot.webmvc.version")
public class VersionProperties { public class WebMvcVersionProperties {
/** /**
* API前缀 * API前缀
* <p> * <p>
@ -20,6 +20,13 @@ public class VersionProperties {
*/ */
private String apiPrefix = "/api"; private String apiPrefix = "/api";
/**
* API后缀
* <p>
* 定义了API的路由后缀用于在URL中区分不同的API版本
*/
private String apiSuffix = "";
public String getApiPrefix() { public String getApiPrefix() {
return apiPrefix; return apiPrefix;
} }
@ -27,4 +34,12 @@ public class VersionProperties {
public void setApiPrefix(String apiPrefix) { public void setApiPrefix(String apiPrefix) {
this.apiPrefix = apiPrefix; this.apiPrefix = apiPrefix;
} }
public String getApiSuffix() {
return apiSuffix;
}
public void setApiSuffix(String apiSuffix) {
this.apiSuffix = apiSuffix;
}
} }

View File

@ -1,7 +1,7 @@
package com.gewuyou.forgeboot.webmvc.version.config package com.gewuyou.forgeboot.webmvc.version.config
import com.gewuyou.forgeboot.core.extension.log import com.gewuyou.forgeboot.core.extension.log
import com.gewuyou.forgeboot.webmvc.version.config.entities.VersionProperties import com.gewuyou.forgeboot.webmvc.version.config.entities.WebMvcVersionProperties
import com.gewuyou.forgeboot.webmvc.version.mapping.ApiVersionRequestMappingHandlerMapping import com.gewuyou.forgeboot.webmvc.version.mapping.ApiVersionRequestMappingHandlerMapping
import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Bean
@ -16,7 +16,7 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandl
* @author gewuyou * @author gewuyou
*/ */
@Configuration @Configuration
@EnableConfigurationProperties(VersionProperties::class) @EnableConfigurationProperties(WebMvcVersionProperties::class)
open class VersionAutoConfiguration { open class VersionAutoConfiguration {
/** /**
* 创建并配置一个 ApiVersionRequestMappingHandlerMapping 实例 * 创建并配置一个 ApiVersionRequestMappingHandlerMapping 实例
@ -29,11 +29,11 @@ open class VersionAutoConfiguration {
*/ */
@Bean @Bean
open fun apiVersionRequestMappingHandlerMapping( open fun apiVersionRequestMappingHandlerMapping(
versionProperties: VersionProperties, webMvcVersionProperties: WebMvcVersionProperties,
corsConfigurationSource: CorsConfigurationSource, corsConfigurationSource: CorsConfigurationSource,
): RequestMappingHandlerMapping { ): RequestMappingHandlerMapping {
log.info("创建 API 版本请求映射处理程序映射") log.info("创建 API 版本请求映射处理程序映射")
return ApiVersionRequestMappingHandlerMapping(versionProperties).also { return ApiVersionRequestMappingHandlerMapping(webMvcVersionProperties).also {
it.order = Int.MIN_VALUE it.order = Int.MIN_VALUE
it.corsConfigurationSource = corsConfigurationSource it.corsConfigurationSource = corsConfigurationSource
} }

View File

@ -1,8 +1,7 @@
package com.gewuyou.forgeboot.webmvc.version.mapping package com.gewuyou.forgeboot.webmvc.version.mapping
import com.gewuyou.forgeboot.webmvc.version.annotation.ApiVersion import com.gewuyou.forgeboot.webmvc.version.annotation.ApiVersion
import com.gewuyou.forgeboot.webmvc.version.config.entities.VersionProperties import com.gewuyou.forgeboot.webmvc.version.config.entities.WebMvcVersionProperties
import org.springframework.core.annotation.AnnotatedElementUtils import org.springframework.core.annotation.AnnotatedElementUtils
import org.springframework.web.bind.annotation.RestController import org.springframework.web.bind.annotation.RestController
import org.springframework.web.servlet.mvc.method.RequestMappingInfo import org.springframework.web.servlet.mvc.method.RequestMappingInfo
@ -12,15 +11,19 @@ import java.lang.reflect.Method
/** /**
*API 版本请求映射处理程序映射 *API 版本请求映射处理程序映射
* *
* 该类主要用于处理带有版本信息的API请求映射通过解析控制器和方法上的@ApiVersion注解
* 结合版本配置信息动态生成包含版本路径的请求映射信息
*
* @since 2025-02-04 20:30:44 * @since 2025-02-04 20:30:44
* @author gewuyou * @author gewuyou
*/ */
class ApiVersionRequestMappingHandlerMapping( class ApiVersionRequestMappingHandlerMapping(
private val versionProperties: VersionProperties private val webMvcVersionProperties: WebMvcVersionProperties,
) : RequestMappingHandlerMapping() { ) : RequestMappingHandlerMapping() {
/** /**
* 判断是否处理特定类型的Bean * 判断是否处理特定类型的Bean
* 仅处理标注了 @RestController 注解的类 * 仅处理标注了 @RestController 注解的类
*
* @param beanType 要判断的Bean类型 * @param beanType 要判断的Bean类型
* @return 如果类型标注了 @RestController则返回true否则返回false * @return 如果类型标注了 @RestController则返回true否则返回false
*/ */
@ -33,6 +36,7 @@ class ApiVersionRequestMappingHandlerMapping(
* 获取方法的映射信息 * 获取方法的映射信息
* 首先尝试从方法上获取 @ApiVersion 注解如果不存在则尝试从类上获取 * 首先尝试从方法上获取 @ApiVersion 注解如果不存在则尝试从类上获取
* 如果存在 @ApiVersion 注解则会根据注解中的版本信息来组合新地映射路径 * 如果存在 @ApiVersion 注解则会根据注解中的版本信息来组合新地映射路径
*
* @param method 方法对象 * @param method 方法对象
* @param handlerType 处理器类型 * @param handlerType 处理器类型
* @return 可能包含版本信息的 RequestMappingInfo如果不存在 @ApiVersion 注解则返回原始的映射信息 * @return 可能包含版本信息的 RequestMappingInfo如果不存在 @ApiVersion 注解则返回原始的映射信息
@ -57,20 +61,29 @@ class ApiVersionRequestMappingHandlerMapping(
/** /**
* 组合版本路径支持多个版本 * 组合版本路径支持多个版本
* 根据版本配置信息和@ApiVersion注解中的版本生成包含版本路径的请求映射信息
*
* @param originalMapping 原始的 RequestMappingInfo * @param originalMapping 原始的 RequestMappingInfo
* @param versions 版本数组 * @param versions 版本数组
* @return 组合后的 RequestMappingInfo * @return 组合后的 RequestMappingInfo
*/ */
private fun combineVersionMappings( private fun combineVersionMappings(
originalMapping: RequestMappingInfo, originalMapping: RequestMappingInfo,
versions: Array<out String> versions: Array<out String>,
): RequestMappingInfo { ): RequestMappingInfo {
return versions return versions
.map { .map {
val apiSuffix = webMvcVersionProperties.apiSuffix
if (apiSuffix.isNotBlank()) {
RequestMappingInfo
.paths("${webMvcVersionProperties.apiPrefix}/$it/$apiSuffix")
.build()
} else {
// 加上版本前缀 // 加上版本前缀
RequestMappingInfo RequestMappingInfo
.paths("${versionProperties.apiPrefix}/$it") .paths("${webMvcVersionProperties.apiPrefix}/$it")
.build() .build()
}
}.reduce { }.reduce {
// 组合 // 组合
acc, mapping -> acc, mapping ->