You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring为何在application/json GET请求中解码加号?该如何处理?

问题解析与解决方案

一、为什么Spring会把查询参数中的+解码为空格?

这其实是HTTP标准的规定,和请求体的Content-Type无关!

URL的查询字符串(即?后面的部分)遵循application/x-www-form-urlencoded的编码规则——这个规则里明确规定,+用来表示空格(这是早期HTML表单提交的约定,后来被纳入HTTP规范)。不管你的请求体是JSON、XML还是其他格式,只要参数在URL的查询串里,Spring就会按照这个标准规则解码,把+转成空格。

你提到的SPR-6291 Bug修复,其实针对的是POST请求体中的表单数据错误解码+的问题,和URL查询参数的解码逻辑完全无关。所以这个修复不影响你遇到的场景,哪怕你的Spring版本高于5.0.0,查询参数的解码规则也不会改变。

二、如何禁用这个行为?

如果确实需要在服务器端保留原始的+号,有两种方式,但都不推荐(原因后面说明):

  1. 直接获取原始查询字符串自行解析
    绕过Spring的自动解码,从HttpServletRequest中拿到未解码的原始查询串,自己解析参数:

    @GetMapping
    public void foo(HttpServletRequest request) {
        String rawQuery = request.getQueryString();
        // 自行解析rawQuery,比如按&分割,再按=分割参数键值对
        // 此时email参数的原始值就是foo+bar@example.com
        String email = Arrays.stream(rawQuery.split("&"))
                .filter(param -> param.startsWith("email="))
                .map(param -> param.substring(6))
                .findFirst()
                .orElse(null);
        System.out.println(email); // 输出foo+bar@example.com
    }
    
  2. 自定义参数解析器
    注册一个自定义的RequestParamMethodArgumentResolver,覆盖默认的解码逻辑,让它不对+进行转换。这种方式比较复杂,需要深入Spring的参数解析机制,不建议轻易修改,容易破坏其他参数的正常解析。

三、应该禁用它,还是客户端编码+为%2B?

强烈推荐在客户端对+进行编码为%2B,这是符合HTTP规范的正确做法。

因为在URL查询参数中,+的语义就是空格,如果你要传递字面意义的+,就必须编码为%2B。这样不仅能解决Spring解码的问题,还能保证你的接口在其他客户端(比如Postman、curl)调用时也能正常工作。

对于使用Spring RestTemplate的客户端,正确的编码方式如下:

方式1:使用UriComponentsBuilder(推荐)

UriComponentsBuilder会自动对特殊字符进行规范编码,包括把+转成%2B:

UriComponents uriComponents = UriComponentsBuilder.fromHttpUrl("http://localhost/foo")
        .queryParam("email", "foo+bar@example.com")
        .build(true); // true表示强制编码所有需要转义的字符

ResponseEntity<Void> response = restTemplate.getForEntity(uriComponents.toUri(), Void.class);

方式2:使用UriTemplate

UriTemplate在扩展参数时也会自动编码特殊字符:

UriTemplate template = new UriTemplate("http://localhost/foo?email={email}");
URI uri = template.expand("foo+bar@example.com");
// 此时uri中的email参数会被编码为foo%2Bbar@example.com

总结

  • Spring的解码行为是符合HTTP规范的,和请求体类型无关;
  • 不建议修改服务器端的解码逻辑,容易破坏规范兼容性;
  • 最优方案是在客户端使用Spring提供的URL构建工具,自动将+编码为%2B,遵循标准。

内容的提问来源于stack exchange,提问作者Pablo Fernandez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:57:39