danuri
오늘의 기록
danuri
전체 방문자
오늘
어제
  • 오늘의 기록 (307)
    • java (150)
      • java (33)
      • spring (63)
      • jpa (36)
      • querydsl (7)
      • intelliJ (9)
    • kotlin (8)
    • python (24)
      • python (10)
      • data analysis (13)
      • crawling (1)
    • ddd (2)
    • chatgpt (2)
    • algorithm (33)
      • theory (9)
      • problems (23)
    • http (8)
    • git (8)
    • database (5)
    • aws (12)
    • devops (10)
      • docker (6)
      • cicd (4)
    • book (44)
      • clean code (9)
      • 도메인 주도 개발 시작하기 (10)
      • 자바 최적화 (11)
      • 마이크로서비스 패턴 (0)
      • 스프링으로 시작하는 리액티브 프로그래밍 (14)
    • tistory (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

인기 글

태그

  • 등가속도 운동
  • ChatGPT
  • Bitmask
  • CICD
  • 자바 최적화
  • Saving Plans
  • Thymeleaf
  • nuribank
  • mockito
  • Kotlin
  • Security
  • 도메인 주도 설계
  • reactive
  • PostgreSQL
  • gitlab
  • RDS
  • JPA
  • Java
  • Database
  • AWS
  • Spring
  • 트랜잭션
  • DDD
  • S3
  • 마이크로서비스패턴
  • Jackson
  • POSTGIS
  • SWAGGER
  • docker
  • connection

최근 댓글

최근 글

hELLO · Designed By 정상우.
danuri

오늘의 기록

[Spring] AWS S3에서 Spring Boot로 파일 다운로드
java/spring

[Spring] AWS S3에서 Spring Boot로 파일 다운로드

2021. 8. 5. 22:33

 

프로젝트 중 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
    'java/spring' 카테고리의 다른 글
    • [Spring] SpringBatch를 사용해 csv 파일 읽어 DB에 저장
    • [Spring] AWS S3, csv 파일 읽어서 DB에 저장
    • [Spring] Jasypt를 이용한 암호화
    • [Spring] 스프링 부트, 라이브러리 버전 맞추기
    danuri
    danuri
    IT 관련 정보(컴퓨터 지식, 개발)를 꾸준히 기록하는 블로그입니다.

    티스토리툴바