路径变量为空致404,如何让请求进入服务并抛对应异常?
解决Spring MVC中空路径变量导致404的问题
当发起包含空路径变量的GET请求(如
hello//me)时,Spring MVC返回404 Not Found,但希望该请求能进入控制器方法,并抛出路径变量为空的异常,而非直接返回404。正常请求hello/123/me可以正常处理,当前控制器代码如下:
@GetMapping(value = "/hello/{uuid}/me") public ResponseEntity<Void> hello( @PathVariable(name = "uuid", required = false) String uuid){
核心原因
Spring MVC默认会对请求路径做规范化处理,将多个连续的斜杠//合并为单个斜杠/,导致hello//me被解析为hello/me,与定义的/hello/{uuid}/me路径模板不匹配,直接返回404,请求无法到达控制器方法。
解决步骤
1. 关闭路径规范化,允许空路径变量匹配
需要配置Spring MVC的路径解析器,使其保留连续斜杠,让空的路径变量能被识别:
方式一:通过配置文件(Spring Boot 2.6+)
在application.properties中添加以下配置:
# 使用PathPatternParser作为路径匹配策略 spring.mvc.pathmatch.matching-strategy=path-pattern-parser # 允许路径中存在连续斜杠 spring.mvc.pathpattern.parser.match-doubleslash=true
方式二:通过Java配置
创建配置类自定义PathPatternParser:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.util.pattern.PathPatternParser; @Configuration public class PathMatchingConfig { @Bean public PathPatternParser pathPatternParser() { PathPatternParser parser = new PathPatternParser(); parser.setAllowDoubleslash(true); return parser; } }
2. 修改控制器方法,添加空值校验
配置完成后,hello//me会被解析为uuid为空字符串,请求会进入控制器方法。此时可以通过两种方式抛出异常:
方式一:手动判断抛出异常
@GetMapping(value = "/hello/{uuid}/me") public ResponseEntity<Void> hello( @PathVariable(name = "uuid") String uuid) { if (uuid == null || uuid.isBlank()) { throw new IllegalArgumentException("路径变量uuid不能为空"); } // 执行业务逻辑 return ResponseEntity.ok().build(); }
方式二:使用JSR-380校验注解
先确保项目引入spring-boot-starter-validation依赖,再修改控制器:
import jakarta.validation.constraints.NotBlank; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import org.springframework.http.ResponseEntity; @RestController @Validated // 必须添加此注解启用校验 public class HelloController { @GetMapping(value = "/hello/{uuid}/me") public ResponseEntity<Void> hello( @PathVariable(name = "uuid") @NotBlank(message = "路径变量uuid不能为空") String uuid) { // 执行业务逻辑 return ResponseEntity.ok().build(); } }
此时若uuid为空,Spring会抛出ConstraintViolationException,可通过全局异常处理器统一处理返回格式。
内容的提问来源于stack exchange,提问作者Abdel
相关产品推荐
相关产品推荐

