使用Java压缩JSON列表上传S3时遇到InvalidDefinitionException错误如何解决
错误根因
你遇到的报错本质是逻辑错位导致的:
- 直接触发异常的代码是
objectMapper.writeValueAsBytes(objectOutputStream):Jackson的ObjectMapper是用来序列化Java对象为JSON格式的,你传入的是ObjectOutputStream流对象本身,Jackson没有对应这个类的序列化规则,也找不到可序列化的属性,因此抛出了InvalidDefinitionException。 - 深层逻辑错误:你之前通过
ObjectOutputStream写入JsonNode的操作,是用Java原生序列化机制把对象写到了Gzip压缩流中,这部分结果你完全没有获取到,反而去序列化输出流这个工具类对象,完全偏离了获取压缩后JSON数据的目标。且Java原生序列化的结果只能通过Java反序列化读取,通用性极差,不符合存储JSON数据的预期。
修复方案
调整流处理逻辑,直接将JsonNode序列化为JSON字节后写入Gzip压缩流,最终取压缩后的字节上传S3即可,参考代码如下:
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream; import com.amazonaws.services.s3.model.ObjectMetadata; // 省略外层业务逻辑 ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); // 用try-with-resources自动关流,避免手动关流遗漏 try (GzipCompressorOutputStream gzipOut = new GzipCompressorOutputStream(byteOut); OutputStreamWriter writer = new OutputStreamWriter(gzipOut, StandardCharsets.UTF_8)) { ObjectMapper objectMapper = new ObjectMapper(); for (JsonNode record : payload) { // 把每个JsonNode转成JSON字符串写入压缩流 writer.write(objectMapper.writeValueAsString(record)); // 可选:加换行生成JSON Lines格式,方便后续逐行读取解析 writer.write("\n"); } } // 直接获取压缩后的最终字节数组 byte[] bytesToWrite = byteOut.toByteArray(); // 上传S3逻辑 ObjectMetadata omd = new ObjectMetadata(); omd.setContentType("application/x-gzip"); omd.setContentEncoding("gzip"); omd.setContentLength(bytesToWrite.length); s3.putObject(bucketName, keyName, new ByteArrayInputStream(bytesToWrite), omd);
内容的提问来源于stack exchange,提问作者Madhuri
相关产品推荐
相关产品推荐

