Spring Boot项目本地运行正常 部署Linux服务器访问接口报400错误
问题排查结论
400 Bad Request的核心原因是业务参数中包含未编码的URL保留字符:
- 你的发票号格式为
INV2022/01,其中/是HTTP URI规范定义的保留字符,默认作为URL路径分隔符使用,作为查询参数传递时必须做百分号编码转义为%2F - Thymeleaf的
@{...}语法默认不会转义查询参数中的/字符,因此生成的链接中斜杠保持原始形态,不符合严格的URI规范 - 本地Windows开发环境下Spring Boot内嵌的Tomcat对非规范URL兼容性较高,未拦截未编码的斜杠,所以功能正常
- Linux部署环境无论是内嵌Tomcat、外部Tomcat还是前置的Nginx/Apache反向代理,默认都开启了严格的URI合规校验,直接拦截了带未编码斜杠的请求,没有转发到业务代码,因此返回400错误
解决方法
方法1:对查询参数做强制URL编码(推荐,无安全风险)
修改Thymeleaf模板中的链接生成逻辑,调用内置URI工具类对参数做专门的查询参数转义,确保所有特殊字符被正确编码:
<td > <a th:href="@{/generateAndGetInvoicePDF(invoiceNo=${#uris.escapeQueryParam(invoiceList.invoiceNo, 'UTF-8')})}" style="text-decoration: none;" th:text="${invoiceList.invoiceNo}"> </a> </td>
编码后生成的链接中斜杠会被转义为%2F,完全符合URI规范,所有环境的服务器都能正常接收,Spring MVC会自动将%2F解码回/,控制器中拿到的invoiceNo参数和原始值完全一致,不影响业务逻辑。
方法2:放宽服务器URI校验规则(不推荐,存在安全隐患)
如果暂时无法修改模板代码,可以通过配置放宽Tomcat对查询参数的字符校验,允许未编码的斜杠出现在查询参数中:
如果是Spring Boot内嵌Tomcat部署,在配置文件中添加:
server.tomcat.relaxed-query-chars=/
如果是独立外部Tomcat部署,修改Tomcat目录下conf/catalina.properties文件,添加配置:
tomcat.util.http.parser.HttpParser.requestTargetAllow=/
该配置会降低服务器对恶意路径遍历请求的防御能力,非特殊场景不建议使用。
方法3:优化业务字段规则(长期方案)
在业务设计层面,尽量避免在发票号、订单号这类需要作为URL参数传递的字段中使用/、?、&、#这类URL特殊保留字符,从根源上规避URL编码兼容问题。
内容的提问来源于stack exchange,提问作者Arun Ginnaram
相关产品推荐
相关产品推荐

