如何为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
相关产品推荐
相关产品推荐

