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
相关产品推荐
相关产品推荐

