Spring Boot中如何读取S3桶内多行JSON文件为对象列表
在Spring Boot中从AWS S3读取多行JSON文件为对象列表
前提准备
确保Spring Boot项目中引入AWS SDK for Java v2的S3依赖,以及Jackson用于JSON反序列化:
<!-- Maven依赖 --> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>s3</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> <!-- 若使用Spring Boot AWS Starter,可替换引入 --> <dependency> <groupId>io.awspring.cloud</groupId> <artifactId>spring-cloud-starter-aws</artifactId> <version>3.0.1</version> <!-- 对应Spring Boot版本选择适配版本 --> </dependency>
1. 定义Java实体类
对应JSON结构创建实体类:
import com.fasterxml.jackson.annotation.JsonProperty; public class Person { @JsonProperty("name") private String name; @JsonProperty("surname") private String surname; // 无参构造器(Jackson反序列化必需) public Person() {} // 全参构造器、getter、setter public Person(String name, String surname) { this.name = name; this.surname = surname; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSurname() { return surname; } public void setSurname(String surname) { this.surname = surname; } }
2. 实现S3读取并转换为对象列表
创建服务类,通过S3 Select查询文件并将结果收集为对象列表:
import software.amazon.awssdk.core.ResponseInputStream; import software.amazon.awssdk.services.s3.S3Client; import software.amazon.awssdk.services.s3.model.*; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.stereotype.Service; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; @Service public class S3JsonService { private final S3Client s3Client; private final ObjectMapper objectMapper; // 构造注入S3客户端和ObjectMapper public S3JsonService(S3Client s3Client, ObjectMapper objectMapper) { this.s3Client = s3Client; this.objectMapper = objectMapper; } public List<Person> readMultiLineJsonFromS3(String bucketName, String key) throws IOException { // 构建S3 Select查询请求 SelectObjectContentRequest request = SelectObjectContentRequest.builder() .bucket(bucketName) .key(key) .expression("SELECT * FROM S3Object") // 查询文件所有内容 .expressionType(ExpressionType.SQL) .inputSerialization(InputSerialization.builder() .json(JSONInput.builder() .type(JSONType.LINES) // 指定输入为每行一个独立JSON对象 .build()) .build()) .outputSerialization(OutputSerialization.builder() .json(JSONOutput.builder().build()) // 输出为JSON格式 .build()) .build(); List<Person> personList = new ArrayList<>(); // 执行查询并处理响应流 try (ResponseInputStream<SelectObjectContentResponse> responseInputStream = s3Client.selectObjectContent(request)) { BufferedReader reader = new BufferedReader(new InputStreamReader(responseInputStream)); String line; while ((line = reader.readLine()) != null) { // 过滤S3 Select返回的统计信息行 if (!line.startsWith("{\"Stats\":")) { Person person = objectMapper.readValue(line, Person.class); personList.add(person); } } } catch (S3Exception e) { throw new IOException("S3查询失败: " + e.awsErrorDetails().errorMessage(), e); } return personList; } }
3. 配置S3客户端
在Spring Boot中可通过配置类手动创建S3客户端:
import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.s3.S3Client; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class AwsConfig { @Bean public S3Client s3Client() { return S3Client.builder() .region(Region.US_EAST_1) // 替换为你的S3桶所在区域 .build(); } }
也可通过application.properties配置:
cloud.aws.region.static=us-east-1 cloud.aws.credentials.access-key=你的访问密钥 cloud.aws.credentials.secret-key=你的秘密密钥
关键说明
- S3 Select参数:必须指定
JSONType.LINES,否则S3无法正确解析每行独立的JSON对象。 - 响应过滤:S3 Select返回的流会包含统计信息行,需过滤后再反序列化数据。
- 资源管理:使用try-with-resources确保流和客户端资源自动关闭,避免内存泄漏。
内容的提问来源于stack exchange,提问作者user1555190
相关产品推荐
相关产品推荐

