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)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

인기 글

태그

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

최근 댓글

최근 글

hELLO · Designed By 정상우.
danuri

오늘의 기록

java/spring

[Spring] AWS S3, csv 파일 읽어서 DB에 저장

2021. 8. 5. 22:58

프로젝트 중 AWS S3에서 특정 버킷의 파일을 읽어 DB에 저장해야 하는 상황이 생겨 기록을 한다.

 

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;

    @PostMapping("/csv_read")
    public ResponseEntity<String> read(@PathVariable String fileName) throws IOException {
        s3Service.readObject("food.csv");
        return new ResponseEntity<>("success", HttpStatus.OK);
    }
}

readObject(): 인자("food.csv")을 이름으로 갖는 파일을 읽어서 DB에 저장하는 메서드

만약 해당 파일이 버킷에 없으면 에러가 발생한다.

 

<food.csv 예시>

1,계란

2,라면

3,시금치

...

 

<Food>

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
public class Food {

    @Id
    @Column(name = "food_id")
    private String id;

    //==생성자==//
    public Food(String id, String name) {
        this.id = id;
        this.name = name;
    }
}

food.csv의 데이터를 Food 엔티티 저장해 DB에 저장하는 것이 목적이다.

 

<Service>

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class S3Service {

    private final AmazonS3 amazonS3;
    private final EntityManager em;

    @Value("${aws.s3.bucket}")
    private String bucket;

    /**
     * S3 bucket 파일 읽어 DB에 저장
     */
    @Transactional
    public void readObject(String storedFileName) throws IOException {
        S3Object o = amazonS3.getObject(new GetObjectRequest(bucket, storedFileName));
        S3ObjectInputStream ois = null;
        BufferedReader br = null;
        
        // Read the CSV one line at a time and process it.
        try {
            ois = o.getObjectContent();
            System.out.println ("ois = " + ois);
            br = new BufferedReader (new InputStreamReader(ois, "UTF-8"));
            
            String line;
            while ((line = br.readLine()) != null) {
                // Store 1 record in an array separated by commas
                String[] data = line.split(",", 0);

                Food food = new Food(data[0], data[1]);
                em.persist(food);
            }
        } finally {
            if(ois != null){
                ois.close();
            }
            if(br != null){
                br.close();
            }
        }
    }
}

컨트롤러에서 호출한 readObject()메서드가 있는 서비스 계층

부분적으로 간단히 살펴보자.

 

S3Object o = amazonS3.getObject(new GetObjectRequest(bucket, storedFileName));

aws s3의 버킷과 파일 이름(bucket, storedFileName)을 전달하고 매칭이 되면 S3Object를 반환한다.

 

br = new BufferedReader (new InputStreamReader(ois, "UTF-8"));

BufferedReader를 통해 csv파일을 한 줄 씩 읽는다.

 

String line;
while ((line = br.readLine()) != null) {
    // Store 1 record in an array separated by commas
    String[] data = line.split(",", 0);

    Food food = new Food(data[0], data[1]);
    em.persist(food);
}

1. 한 줄 씩 불러와 ","를  기준으로 문자열을 split 한뒤

2. Food 생성자 형식에 맞게 엔티티를 생성하고

3. 엔티티를 DB에 저장한다.

'java > spring' 카테고리의 다른 글

[Spring] Spring Jdbc - batchUpdate()를 사용한 bulk Insert 최적화  (0) 2021.08.06
[Spring] SpringBatch를 사용해 csv 파일 읽어 DB에 저장  (4) 2021.08.06
[Spring] AWS S3에서 Spring Boot로 파일 다운로드  (0) 2021.08.05
[Spring] Jasypt를 이용한 암호화  (2) 2021.07.21
[Spring] 스프링 부트, 라이브러리 버전 맞추기  (0) 2021.05.23
    'java/spring' 카테고리의 다른 글
    • [Spring] Spring Jdbc - batchUpdate()를 사용한 bulk Insert 최적화
    • [Spring] SpringBatch를 사용해 csv 파일 읽어 DB에 저장
    • [Spring] AWS S3에서 Spring Boot로 파일 다운로드
    • [Spring] Jasypt를 이용한 암호화
    danuri
    danuri
    IT 관련 정보(컴퓨터 지식, 개발)를 꾸준히 기록하는 블로그입니다.

    티스토리툴바