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

如何为Spring REST控制器设置多基础路径(按包配置公共路径)

当然可以!Spring MVC完全支持这种按包批量设置路径前缀的需求,不用在每个控制器里重复写那些冗长的前缀,和你之前用CXF的思路一模一样。下面给你两种实用的实现方式:

方法一:使用@ControllerAdvice(推荐,Spring Boot 2.6+适用)

这是最简洁的方式,利用Spring的控制器增强特性,给指定包下的所有控制器统一添加路径前缀:

首先创建两个增强类,分别对应不同的包和前缀:

// 给domain1包下的所有控制器添加/api/domain1前缀
@ControllerAdvice(basePackages = "com.example.domain1")
@RequestMapping("/api/domain1")
public class Domain1ControllerPrefixAdvice {}

// 给domain2包下的所有控制器添加/api/domain2前缀
@ControllerAdvice(basePackages = "com.example.domain2")
@RequestMapping("/api/domain2")
public class Domain2ControllerPrefixAdvice {}

然后你的控制器类只需要定义自身的路径部分即可,不用再重复前缀:

@RestController
@RequestMapping("facade1path") // 最终路径是/api/domain1/facade1path
public class Facade1 {
    // 示例端点
    @GetMapping("/hello")
    public String hello() {
        return "Hello from Facade1!";
    }
}

这种方式完全复刻了你之前CXF配置的逻辑,代码简洁易维护,新增包的话只需要再添加一个对应的@ControllerAdvice类就行。

方法二:自定义RequestMappingHandlerMapping(兼容旧版本Spring)

如果你的Spring Boot版本低于2.6,或者需要更灵活的前缀规则,可以通过自定义请求映射处理器来实现:

@Configuration
public class GlobalPathPrefixConfig {

    @Bean
    public RequestMappingHandlerMapping customRequestMappingHandlerMapping() {
        return new RequestMappingHandlerMapping() {
            @Override
            protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
                // 先获取控制器方法本身的映射信息
                RequestMappingInfo originalMapping = super.getMappingForMethod(method, handlerType);
                if (originalMapping != null) {
                    // 根据控制器所在包获取对应的前缀
                    String prefix = resolvePrefixFromPackage(handlerType);
                    if (prefix != null) {
                        // 将前缀和原有映射组合
                        RequestMappingInfo prefixMapping = RequestMappingInfo.paths(prefix).build();
                        originalMapping = prefixMapping.combine(originalMapping);
                    }
                }
                return originalMapping;
            }

            private String resolvePrefixFromPackage(Class<?> handlerType) {
                String packageName = handlerType.getPackageName();
                if (packageName.startsWith("com.example.domain1")) {
                    return "/api/domain1";
                } else if (packageName.startsWith("com.example.domain2")) {
                    return "/api/domain2";
                }
                // 可以根据需要扩展更多包的前缀规则
                return null;
            }
        };
    }
}

配置完成后,你的控制器写法和方法一完全一样,只需要定义自身的路径部分,前缀会自动根据包名添加。

两种方法都能完美实现你要的效果,推荐优先使用方法一,代码更简洁直观。

内容的提问来源于stack exchange,提问作者Michal Aron

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:44:34