如何修复上传至S3的JSON文件内容显示为[value: string]而非实际数据
问题原因
你遇到的核心问题是**JSONdata.toString()没有返回实际的JSON数据**:
results.toJSON返回的是Dataset[String]类型,它的toString()方法输出的是数据集的结构描述(比如[value: string]),而非所有JSON行拼接成的完整内容。- 你以为打印出的“有效JSON”大概率是测试时的误操作(比如调用了
show()而非打印JSONstring),实际JSONstring的值就是[value: string],这也是S3文件内容异常的直接原因。
解决方案
1. 正确生成完整JSON字符串
由于你的数据量很小,可以直接收集Dataset[String]的所有元素,拼接成符合需求的格式:
- 若需要JSON数组格式(所有对象包裹在
[]中):val JSONstring = JSONdata.collect().mkString("[", ",", "]") - 若需要JSON Lines格式(每行一个独立JSON对象):
val JSONstring = JSONdata.collect().mkString("\n")
2. 正确上传到S3
提供两种上传方式供选择:
方式一:直接上传字符串(简单快捷)
AWS Java SDK支持直接传入字符串的putObject重载方法:
val result = amazonS3Client.putObject(bucketName, objectKey, JSONstring)
方式二:通过InputStream上传(支持元数据配置)
如果需要设置文件的Content-Type、编码等元数据,推荐使用此方式:
import java.io.ByteArrayInputStream import java.nio.charset.StandardCharsets import com.amazonaws.services.s3.model.ObjectMetadata // 将字符串转为InputStream val inputStream = new ByteArrayInputStream(JSONstring.getBytes(StandardCharsets.UTF_8)) // 配置元数据 val metadata = new ObjectMetadata() metadata.setContentType("application/json") metadata.setContentLength(JSONstring.getBytes(StandardCharsets.UTF_8).length) // 执行上传 val result = amazonS3Client.putObject(bucketName, objectKey, inputStream, metadata)
修正后的完整代码
import com.amazonaws.services.s3.AmazonS3Client import com.amazonaws.auth.BasicAWSCredentials import com.amazonaws.ClientConfiguration import java.io.ByteArrayInputStream import java.nio.charset.StandardCharsets import com.amazonaws.services.s3.model.ObjectMetadata val query = "[My SQL query]"; val results = spark.sql(query); val JSONdata = results.toJSON; // 正确生成JSON数组格式字符串 val JSONstring = JSONdata.collect().mkString("[", ",", "]") try { println(JSONstring); // 现在会打印实际的JSON数据 println(JSONstring.getClass); // 确认类型为String // 方式一:直接上传字符串 // val result = amazonS3Client.putObject(bucketName, objectKey, JSONstring); // 方式二:通过InputStream上传并配置元数据 val inputStream = new ByteArrayInputStream(JSONstring.getBytes(StandardCharsets.UTF_8)) val metadata = new ObjectMetadata() metadata.setContentType("application/json") metadata.setContentLength(JSONstring.getBytes(StandardCharsets.UTF_8).length) val result = amazonS3Client.putObject(bucketName, objectKey, inputStream, metadata) println("Result: " + result.getETag()); } catch { case e: Exception => println("Error: " + e.getMessage()); }
内容的提问来源于stack exchange,提问作者Alex Kerr
相关产品推荐
相关产品推荐

