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

Spring Boot中RestTemplate.exchange()执行后Authorization头值损坏问题

问题根因

异常出现的Â字符是字符编码不匹配导致的:
原始请求头中Bearer与令牌之间的空格不是普通ASCII空格(U+0020),而是UTF-8编码的非断空格(NBSP,U+00A0)。HTTP头默认传输编码为ISO-8859-1,当UTF-8编码的NBSP(0xC2A0)按照ISO-8859-1解析时,会被拆分为Â(对应字节0xC2)和隐形非断空格(对应字节0xA0),最终呈现出你看到的异常授权头。

修复方案

1. 修复拦截器逻辑

读取授权头后先清理所有异常空白字符,再写入新请求头即可:

public class HeaderLoginInterceptor implements ClientHttpRequestInterceptor {

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        HttpServletRequest previousRequest = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String authHeader = previousRequest.getHeader(AUTHORIZATION);
        if(authHeader != null){
            // 清理所有异常空白字符,替换为普通ASCII空格,再去除首尾多余空白
            String cleanedAuthHeader = authHeader.trim().replaceAll("\\s+", " ");
            request.getHeaders().add(AUTHORIZATION, cleanedAuthHeader);
        }
        return execution.execute(request, body);
    }

}

2. 修复直接添加授权头的代码

你当前直接加头的代码存在逻辑错误:创建的headers对象没有传入HttpEntity,反而传入了新的空HttpHeaders对象,导致配置不生效,正确写法如下:

HttpServletRequest previousRequest = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
HttpHeaders headers = new HttpHeaders();
String authHeader = previousRequest.getHeader(AUTHORIZATION);
if (authHeader != null) {
    // 同样做空白字符清理
    String cleanedAuthHeader = authHeader.trim().replaceAll("\\s+", " ");
    headers.add(AUTHORIZATION, cleanedAuthHeader);
}
// 将填充好的headers传入HttpEntity
HttpEntity<?> httpEntity = new HttpEntity<>(headers);

可选兼容配置

如果上游服务无法修改返回的头格式,可给RestTemplate配置强制使用UTF-8解析请求头,该方案兼容性不如空白清理方案,优先选择前两种修复方式。

内容的提问来源于stack exchange,提问作者Ignacio Escursell

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 04:36:09