프로젝트 중 AWS S3에서 특정 버킷의 파일을 다운로드 받아야 하는 상황이 생겨 기록을 한다.
build.gradle - 의존성 추가
dependencies {
...
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
...
}
spring boot와 aws를 연동시키기 위해 build.gradle에 spring-cloud-starter-aws를 추가한다.
application.yml - aws 자격 정보 입력
cloud:
aws:
credentials:
instance-profile: false
access-key: {IAM MY_ACCESS_KEY 입력}
secret-key: {IAM MY_SECERT_KEY 입력}
region:
auto: false
static: ap-northeast-2
stack:
auto: false
logging:
level:
com:
amazonaws:
util:
EC2MetadataUtils: error
aws:
s3:
bucket: {버킷 이름}
aws 계정에 해당하는 access-key, secret-key를 입력하고
접근을 원하는 버킷을 입력한다.
AWS 계정 연결
@Configuration
public class S3Config {
@Value("${cloud.aws.credentials.access-key}")
private String accessKey;
@Value("${cloud.aws.credentials.secret-key}")
private String secretKey;
@Value("${cloud.aws.region.static}")
private String region;
@Bean
@Primary
public BasicAWSCredentials awsCredentialsProvider(){
BasicAWSCredentials basicAWSCredentials = new BasicAWSCredentials(accessKey, secretKey);
return basicAWSCredentials;
}
@Bean
public AmazonS3 amazonS3() {
AmazonS3 s3Builder = AmazonS3ClientBuilder.standard()
.withRegion(region)
.withCredentials(new AWSStaticCredentialsProvider(awsCredentialsProvider()))
.build();
return s3Builder;
}
}
Amazon IAM계정과 연결하기 위한 Config클래스를 생성한다.
S3 버킷에 있는 파일 다운로드하기
<Controller>
@Controller
@RequiredArgsConstructor
public class S3Controller {
private final S3Service s3Service;
@GetMapping("/csv_download/{fileName}")
public ResponseEntity<byte[]> download(@PathVariable String fileName) throws IOException {
return s3Service.getObject(fileName);
}
}
경로에 입력한 {fileName}을 이름으로 갖는 파일을 로컬에 다운로드 받는다.
만약 해당 파일이 버킷에 없으면 에러가 발생한다.
<Service>
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class S3Service {
private final AmazonS3 amazonS3;
@Value("${aws.s3.bucket}")
private String bucket;
/**
* S3 bucket 파일 다운로드
*/
public ResponseEntity<byte[]> getObject(String storedFileName) throws IOException {
S3Object o = amazonS3.getObject(new GetObjectRequest(bucket, storedFileName));
S3ObjectInputStream objectInputStream = ((S3Object) o).getObjectContent();
byte[] bytes = IOUtils.toByteArray(objectInputStream);
String fileName = URLEncoder.encode(storedFileName, "UTF-8").replaceAll("\\+", "%20");
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
httpHeaders.setContentLength(bytes.length);
httpHeaders.setContentDispositionFormData("attachment", fileName);
return new ResponseEntity<>(bytes, httpHeaders, HttpStatus.OK);
}
}
컨트롤러에서 호출한 getObject()메서드가 있는 서비스 계층
부분적으로 간단히 살펴보자.
S3Object o = amazonS3.getObject(new GetObjectRequest(bucket, storedFileName));
aws s3의 버킷과 파일 이름(bucket, storedFileName)을 전달하고 매칭이 되면 S3Object를 반환한다.
httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
전송하는 파일의 종류에 따라 Content-Type을 지정해준다.
이미지는 "image/jpeg" 같은 형식으로, 기타 파일은 "application/octet-stream"을 넣어준다.
나는 CSV 파일을 받기 위해 "application/octet-stream"을 사용한다.
파일 다운로드
이제 URL을 입력하면 파일을 다운로드 받을 수 있다.
'java > spring' 카테고리의 다른 글
[Spring] SpringBatch를 사용해 csv 파일 읽어 DB에 저장 (4) | 2021.08.06 |
---|---|
[Spring] AWS S3, csv 파일 읽어서 DB에 저장 (0) | 2021.08.05 |
[Spring] Jasypt를 이용한 암호화 (2) | 2021.07.21 |
[Spring] 스프링 부트, 라이브러리 버전 맞추기 (0) | 2021.05.23 |
타임리프(Thymeleaf) - 스프링 뷰 템플릿 (0) | 2021.05.12 |