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

Spring Boot接收Golang发送的PNG字节数异常,如何提取原始PNG?

问题描述

从Golang服务器向Spring Boot Java应用传输PNG图片时,出现发送与接收字节数不一致的问题,导致无法解析为有效PNG图片。接收端获取到的Content-Type为image/png; charset=utf-8。

请问:

  1. 针对二进制输出,通常会设置charset=utf-8吗?
  2. 这是否是字节数差异的原因?
  3. 如何从响应输入流中提取原始PNG图片?

Go服务器代码片段

w http.ResponseWriter
...
w.Header().Set("Content-Disposition", "attachment; filename=\"" + fileNameOfDownload + "\"")
w.Header().Set("Content-Length", strconv.Itoa(len(result)))

fmt.Println("Length of result: being set:", len(result), strconv.Itoa(len(result)), w.Header().Get("Content-Length"))
//Length of result: being set: 60753 60753 60753

w.Header().Set("Allow", "GET,HEAD,POST,OPTIONS,TRACE")
w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token , Authorization")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Write(result)

Spring Boot客户端代码片段

System.out.println("ResponseDetails:" + httpsCon.getResponseCode() + ":" +
                    httpsCon.getContentType() + ":" + httpsCon.getContentLength() + ":" +
                    httpsCon.getHeaderField("Content-Length"))
//ResponseDetails:200:image/png; charset=utf-8:110286:110286
解决方案

1. 二进制输出是否需要设置charset=utf-8?

不需要。charset参数仅适用于文本类型的Content-Type(比如text/html、application/json),二进制类型(如image/png、application/octet-stream)不存在字符编码的概念,添加charset=utf-8属于错误配置。

2. 这是字节数差异的原因吗?

是的。当Spring Boot看到image/png; charset=utf-8时,会默认以UTF-8编码规则解析响应流,但PNG是二进制数据,这种解析会导致部分字节被错误转换(比如不可编码的字节被替换为UTF-8的替代字符),最终造成接收字节数膨胀、数据损坏,和你遇到的字节数从60753变成110286的情况完全吻合。

3. 如何提取原始PNG图片?

第一步:修复Go服务器的Content-Type配置

在Go代码中明确设置正确的Content-Type,去掉多余的charset参数:

// 添加这行,覆盖默认可能带charset的Content-Type
w.Header().Set("Content-Type", "image/png")

这是从根源解决问题的方式,避免客户端触发错误解析逻辑。

第二步:Spring Boot端强制读取原始字节流

如果暂时无法修改Go服务器,在Spring Boot端必须直接操作字节流,禁止使用字符流或带编码的读取方式:

// 获取原始响应输入流
InputStream inputStream = httpsCon.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int readLen;
// 按字节读取所有数据
while ((readLen = inputStream.read(buffer)) != -1) {
    baos.write(buffer, 0, readLen);
}
// 获取原始PNG字节数组
byte[] rawPngBytes = baos.toByteArray();

// 可直接保存为文件验证
Files.write(Paths.get("output.png"), rawPngBytes);

注意:绝对不要用Reader相关类读取响应,也不要指定任何字符编码,直接以字节为单位处理数据。

额外检查:响应压缩问题

如果Go服务器或中间件(如Nginx)开启了Gzip压缩,而Spring Boot客户端未处理压缩,也会导致字节数异常。可以在Go代码中关闭压缩,或者在Spring Boot请求时添加Accept-Encoding: identity头禁止压缩:

httpsCon.setRequestProperty("Accept-Encoding", "identity");

内容的提问来源于stack exchange,提问作者Krishnan V S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 04:43:16