Spring Boot从2.7.17升级到3.2.1后,400变404问题咨询
Spring Boot 3.2.1路径参数含空格导致404错误的原因与解决办法
问题场景
项目原基于Spring Boot 2.7.17,通过OpenAPI规范生成API接口,业务逻辑无变更,使用RestAssured+Spock做测试。当用含空格的路径参数访问/accounts/{accountId}/statements/{statementId}接口(上下文路径为/open-banking/accounts/v1)时,旧版本返回400错误;升级到Spring Boot 3.2.1后,请求返回404,后端抛出org.springframework.web.servlet.resource.NoResourceFoundException异常。
原因分析
- 路径匹配策略变更:Spring Boot 3.x基于Spring Framework 6.x,默认使用
PathPatternMatcher替代了旧版的AntPathMatcher。新的匹配器对未编码的空格处理逻辑不同——旧版会直接判定参数无效返回400,新版会将带空格的路径识别为静态资源请求,找不到对应资源就返回404。 - URL编码校验更严格:Spring Framework 6.x强化了URL规范的遵守,未编码的空格不再被自动拦截或转换,直接进入路径匹配流程,导致无法匹配到对应的Controller接口。
解决办法
1. 对路径参数做URL编码(推荐)
在测试代码中,将含空格的参数做URL编码(空格转%20),符合HTTP规范的同时能正常匹配接口:
import java.net.URLEncoder def encodedAccountId = URLEncoder.encode("test account", "UTF-8") def encodedStatementId = URLEncoder.encode("stmt 123", "UTF-8") given() .pathParam("accountId", encodedAccountId) .pathParam("statementId", encodedStatementId) .when() .get("/accounts/{accountId}/statements/{statementId}")
2. 回退到旧版路径匹配策略(临时兼容)
如果需要兼容未编码的空格请求(不推荐,不符合HTTP标准),可以配置恢复AntPathMatcher:
配置文件方式(application.yml)
spring: mvc: pathmatch: matching-strategy: ant_path_matcher
配置类方式
@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void configurePathMatch(PathMatchConfigurer configurer) { configurer.setPathMatcher(new AntPathMatcher()); } }
注意:AntPathMatcher属于旧版策略,未来可能被废弃,仅建议作为过渡方案。
3. 通过OpenAPI规范约束参数格式
在OpenAPI规范中添加参数格式校验,禁止路径参数包含空格,从源头避免非法请求:
paths: /accounts/{accountId}/statements/{statementId}: get: parameters: - name: accountId in: path required: true schema: type: string pattern: "^[^\\s]+$" # 匹配不含空格的字符串 - name: statementId in: path required: true schema: type: string pattern: "^[^\\s]+$"
生成的接口代码会自动校验参数,不符合规则的请求会返回400,与旧版本行为一致。
内容的提问来源于stack exchange,提问作者Sergey Tsypanov
相关产品推荐
相关产品推荐

