Spring WebFlux中如何获取@RequestMapping的通配符**值?
在Spring Boot WebFlux中获取@RequestMapping通配符**的值
下面提供几种可行的方案,包括简单直接的写法和可复用的注解式实现:
方案1:使用@PathVariable直接绑定
这是最简洁的方式,修改@RequestMapping的路径定义,用路径变量绑定**匹配的内容:
@Controller @RequestMapping("/template/{rest:**}") public class TemplateController { @GetMapping public Mono<String> getTemplate(@PathVariable("rest") String restPath) { // restPath就是**匹配到的路径内容,比如请求/template/a/b/c时,值为a/b/c return Mono.just(restPath); } }
{rest:**}是Spring路径变量的语法,**表示匹配任意层级的子路径,WebFlux完全支持这种写法,直接就能拿到通配符对应的部分。
方案2:通过ServerHttpRequest解析路径
如果不想修改原有@RequestMapping的写法,可以注入ServerHttpRequest手动解析路径:
@Controller @RequestMapping("/template/**") public class TemplateController { @GetMapping public Mono<String> getTemplate(ServerHttpRequest request) { // 获取应用内的请求路径(自动去掉上下文路径) String fullPath = request.getPath().pathWithinApplication().value(); // 截取"/template/"之后的部分 String restPath = fullPath.substring("/template/".length()); return Mono.just(restPath); } }
注意:如果请求路径是/template/(末尾带斜杠),restPath会是空字符串,可根据业务需求做额外处理。
方案3:自定义注解实现可复用逻辑
如果需要在多个控制器中复用该逻辑,可以自定义注解和参数解析器:
步骤1:定义自定义注解
@Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface RequestMappingWildcard { // 可手动指定@RequestMapping前缀,默认自动从控制器类注解获取 String prefix() default ""; }
步骤2:实现参数解析器
@Component public class RequestMappingWildcardResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter parameter) { return parameter.hasParameterAnnotation(RequestMappingWildcard.class); } @Override public Object resolveArgument(MethodParameter parameter, BindingContext bindingContext, ServerWebExchange exchange) { RequestMappingWildcard annotation = parameter.getParameterAnnotation(RequestMappingWildcard.class); String prefix = annotation.prefix(); // 若未指定前缀,从控制器类的@RequestMapping中提取 if (prefix.isEmpty()) { RequestMapping classMapping = parameter.getContainingClass().getAnnotation(RequestMapping.class); if (classMapping != null && classMapping.value().length > 0) { prefix = classMapping.value()[0].replace("**", ""); } } String fullPath = exchange.getRequest().getPath().pathWithinApplication().value(); return fullPath.startsWith(prefix) ? fullPath.substring(prefix.length()) : ""; } }
步骤3:注册参数解析器
@Configuration public class WebFluxConfig implements WebFluxConfigurer { @Autowired private RequestMappingWildcardResolver wildcardResolver; @Override public void configureArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { resolvers.add(wildcardResolver); } }
使用示例
@Controller @RequestMapping("/template/**") public class TemplateController { @GetMapping public Mono<String> getTemplate(@RequestMappingWildcard String restPath) { return Mono.just(restPath); } }
该方案无需重复编写路径解析逻辑,在任意控制器方法中添加@RequestMappingWildcard注解即可获取通配符对应的值。
内容的提问来源于stack exchange,提问作者Rick
相关产品推荐
相关产品推荐

