You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 04:30:52