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

使用Spring RestTemplate发送加密JSON请求时出现乱码问题

解决Spring RestTemplate发送加密JSON请求乱码问题

嘿,我看你遇到了RestTemplate发送加密JSON时的乱码问题,导致服务端解密失败抛出异常。这个问题大多是因为加密后的二进制数据处理不当,或者RestTemplate的默认编码配置干扰了数据传输。下面是我整理的具体解决方案:

1. 先搞对加密后的数据处理方式

加密后的内容本质是二进制字节流,如果你直接用new String(encryptedBytes)把它转成普通字符串,大概率会因为默认编码(比如UTF-8)无法解析二进制内容而产生乱码。正确的做法是用Base64把加密后的字节编码成安全的可传输字符串,这样不会丢失任何信息:

// 假设encryptJson是你的加密方法,返回加密后的字节数组
byte[] encryptedBytes = encryptJson(yourOriginalJson);
// 转成Base64编码的字符串,确保传输过程中数据完整
String encryptedBase64 = Base64.getEncoder().encodeToString(encryptedBytes);

2. 配置RestTemplate避免自动编码干扰

默认的RestTemplate会对字符串请求体做额外的编码处理,这很可能破坏你已经处理好的加密内容。我们需要调整它的消息转换器:

RestTemplate restTemplate = new RestTemplate();

// 移除默认的StringHttpMessageConverter,它会自动对字符串做编码转换
restTemplate.getMessageConverters().removeIf(converter -> 
    converter instanceof StringHttpMessageConverter);

// 添加自定义的String转换器,指定UTF-8编码,并且禁止自动添加Accept-Charset头
StringHttpMessageConverter customConverter = new StringHttpMessageConverter(StandardCharsets.UTF_8);
customConverter.setWriteAcceptCharset(false);
restTemplate.getMessageConverters().add(customConverter);

发送请求时,记得设置正确的请求头,告诉服务端你发送的是Base64编码的内容:

HttpHeaders headers = new HttpHeaders();
// 可以用text/plain,或者自定义媒体类型比如application/encrypted-json
headers.setContentType(MediaType.TEXT_PLAIN);
HttpEntity<String> requestEntity = new HttpEntity<>(encryptedBase64, headers);

// 发送请求并接收响应
ResponseEntity<String> response = restTemplate.postForEntity(
    "http://你的WebService地址", 
    requestEntity, 
    String.class
);

3. 服务端要对应做解码处理

别忘了服务端这边也要配合,先把接收到的Base64字符串解码回字节数组,再进行解密:

// 服务端获取请求体(这里假设用Spring MVC接收)
@PostMapping("/your-endpoint")
public String handleEncryptedRequest(@RequestBody String encryptedBase64) {
    // 解码Base64字符串到字节数组
    byte[] encryptedBytes = Base64.getDecoder().decode(encryptedBase64);
    // 执行解密操作
    String decryptedJson = decryptBytes(encryptedBytes);
    // 后续业务处理...
    return yourResponse();
}

4. 其他排查小技巧

  • 检查原始JSON的编码:确保你生成原始JSON时用的是UTF-8编码;
  • 开启RestTemplate日志:查看实际发送的请求体和你本地生成的Base64字符串是否一致,排查中间是否有修改:
    <!-- 如果你用logback,添加这个日志配置 -->
    <logger name="org.springframework.web.client.RestTemplate" level="DEBUG"/>
    
  • 直接发送二进制字节流:如果你的加密方案允许,也可以直接发送字节数组,避免Base64转换。此时Content-Type设为application/octet-stream:
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
    HttpEntity<byte[]> requestEntity = new HttpEntity<>(encryptedBytes, headers);
    ResponseEntity<String> response = restTemplate.postForEntity(url, requestEntity, String.class);
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:20:14