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

使用Grails RestResponse获取PNG资源字节数小于预期的问题排查

问题分析与解决方案

我之前在使用Grails Rest客户端获取二进制资源时也碰到过一模一样的问题!字节数总是少一截,后来才发现是默认的消息转换器把二进制数据当成文本处理了,导致数据被错误编码损坏。

问题根源

Grails的RestBuilder默认会注册一系列消息转换器,当你通过restResponse.responseEntity.body获取内容时,如果没有明确指定二进制类型的处理方式,它可能会把PNG这类二进制数据当成字符串来解析(比如用UTF-8编码)。二进制数据里的某些字节序列不符合字符编码规则,会被替换或丢弃,最终导致你拿到的字节数组比实际少。

修复方案

直接从响应的输入流读取原始二进制数据,绕过可能出错的消息转换器处理。修改后的代码如下:

import grails.plugins.rest.client.RestBuilder
import grails.plugins.rest.client.RestResponse
import org.apache.commons.io.IOUtils // 可以用Apache Commons IO,或者自己实现流读取

String url = "http://localhost:8080/rest-endpoint/image.png"
RestBuilder rest = new RestBuilder()
RestResponse restResponse = rest.get(url){
    auth username, password
    accept "image/png"
    contentType "image/png"
}

// 关键:从输入流读取原始二进制
InputStream imageStream = restResponse.inputStream
byte[] png_image = IOUtils.toByteArray(imageStream)
imageStream.close() // 记得关闭流

println "length " + png_image.length

如果不想引入Apache Commons IO,也可以用Java原生的方式读取流:

// 原生Java流读取方式
ByteArrayOutputStream baos = new ByteArrayOutputStream()
byte[] buffer = new byte[1024]
int read
while ((read = imageStream.read(buffer)) != -1) {
    baos.write(buffer, 0, read)
}
byte[] png_image = baos.toByteArray()
baos.close()
imageStream.close()

额外验证点

你也可以检查下响应的Content-Length头,对比你读取到的字节数是否一致:

println "Expected length: " + restResponse.headers.getFirst("Content-Length")

这样修改后,应该就能拿到完整的PNG二进制数据了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:26:03