Spring Boot如何按控制器所在文件夹统一设置路由前缀?
按目录结构统一为Spring控制器添加路由前缀的实现方法
针对你提出的按文件夹(包结构)为控制器统一添加路由前缀的需求,有两种实用的实现方式:
一、全局配置自动匹配包路径前缀
通过自定义RequestMappingHandlerMapping,可以根据控制器所在的包路径自动提取版本前缀(如v1/v2),无需修改现有控制器的注解配置。
实现代码(Kotlin)
import org.springframework.context.annotation.Configuration import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping import org.springframework.web.servlet.mvc.method.annotation.RequestMappingInfo import java.lang.reflect.Method @Configuration class ControllerVersionPrefixConfig : RequestMappingHandlerMapping() { override fun getMappingForMethod(method: Method, handlerType: Class<*>): RequestMappingInfo? { // 获取原始的RequestMapping配置 val originalMapping = super.getMappingForMethod(method, handlerType) ?: return null // 从控制器类的包路径中提取版本标识(如v1/v2) val packageSegments = handlerType.packageName.split(".") val version = packageSegments.lastOrNull() ?: return originalMapping // 仅处理指定的版本前缀 if (version in listOf("v1", "v2")) { // 构造版本前缀的RequestMapping信息 val versionPrefixMapping = RequestMappingInfo.paths("/$version").build() // 将前缀与原始配置合并 return versionPrefixMapping.combine(originalMapping) } return originalMapping } }
使用方式
配置完成后,控制器只需定义自身的路由路径,无需手动添加版本前缀:
@RestController @RequestMapping("/route") class Controller { // 实际路由会自动拼接为 /v1/route(v1包下)或 /v2/route(v2包下) }
二、自定义版本化控制器注解
通过创建带有版本前缀的自定义注解,简化控制器的注解配置,同时保留手动指定路径的灵活性。
方式1:固定版本注解
直接创建对应v1/v2的专用注解:
import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController @Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.RUNTIME) @RestController @RequestMapping("/v1") annotation class RestControllerV1 @Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.RUNTIME) @RestController @RequestMapping("/v2") annotation class RestControllerV2
使用方式
在对应包的控制器上使用注解,方法级的路由会自动拼接版本前缀:
@RestControllerV1 @RequestMapping("/route") class Controller { // 实际路由为 /v1/route }
方式2:可配置版本的通用注解
如果需要更灵活的版本配置,可以创建支持参数的通用注解:
import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController import org.springframework.core.annotation.AliasFor @Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.RUNTIME) @RestController @RequestMapping annotation class VersionedRestController( val version: String, @AliasFor(annotation = RequestMapping::class, attribute = "path") val path: String = "" ) { @AliasFor(annotation = RequestMapping::class, attribute = "path") fun value(): String = "/${version}/${path}" }
使用方式
直接在控制器上指定版本和路径:
@VersionedRestController(version = "v1", path = "route") class Controller { // 实际路由为 /v1/route }
两种方式对比
- 全局配置:无需修改现有控制器,完全基于包结构自动生效,适合批量改造已有项目。
- 自定义注解:更直观,可灵活调整版本和路径,适合新项目或需要精细控制的场景。
内容的提问来源于stack exchange,提问作者KittyCat
相关产品推荐
相关产品推荐

