Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

DOing

[AWS] S3를 Spring에서 사용하기 - 이미지 조회 본문

AWS

[AWS] S3를 Spring에서 사용하기 - 이미지 조회

mangdo 2021. 4. 23. 15:48

이전 포스팅과 이어지는 포스팅입니다.

2021.04.22 - [AWS] - [AWS] S3를 스프링 프로젝트에서 사용하기 - 1 파일업로드

 

[AWS] S3를 스프링 프로젝트에서 사용하기 - 1 파일업로드

[ 버킷 정책 설정 ] 버킷 정책 수정한다. 퍼블릭 엑세스 차단 해제를 하고, 버킷 정책을 설정하는 방법을 사용할 것이다. { "Version": "2012-10-17", "Statement": [ { "Sid": "PublicReadGetObject", "Effect":..

doing7.tistory.com

이전 포스팅에서는 이미지 파일을 업로드 했다면 이번 포스팅에서는 업로드했던 이미지 파일을 조회한다.

[ 기존 코드 - ProductController ]

// image data transmit
@GetMapping("/display")
@ResponseBody
public ResponseEntity<byte[]> getFile(String fileName){
  log.info("fileName: "+ fileName);

  File file = new File("c:\\phoneMall\\upload\\"+fileName);
  ResponseEntity<byte[]> result = null;
  
  try {
    HttpHeaders header = new HttpHeaders();

    // MIME regardless of extention
    header.add("Content-Type", Files.probeContentType(file.toPath()));
    result = new ResponseEntity<>(FileCopyUtils.copyToByteArray(file), header, HttpStatus.OK);
  } catch(IOException e) {
    log.info("wrong file path");
  }
  return result;
}
	

 

[ S3Service ]

이전 포스팅에서 만들었던 S3Service에 presigned URL을 가져오는 함수를 추가하였다.

// get presigned URL
public String getFileURL(String fileName) {
  System.out.println("넘어오는 파일명 : "+fileName);

  // set expiration
  Date expiration = new Date();
  long expTimeMillis = expiration.getTime();
  expTimeMillis += 1000 * 60 * 60; // 1 hour
  expiration.setTime(expTimeMillis);

  // Generate the presigned URL.
  GeneratePresignedUrlRequest generatePresignedUrlRequest =
  	new GeneratePresignedUrlRequest(bucketName, (fileName).replace(File.separatorChar, '/'))
      .withMethod(HttpMethod.GET)
      .withExpiration(expiration);

  return s3Client.generatePresignedUrl(generatePresignedUrlRequest).toString();
}

 

presiginedUrl

 : 모든 객체는 기본적으로 비공개이며, 객체 소유자만 객체에 액세스할 수 있다. 그러나 객체 소유자는 필요할 경우 자신의 보안 자격 증명을 사용하여 일정 기간 동안 객체 다운로드를 허가하는 미리 서명된 URL을 만들어 다른 사용자와 객체를 공유할 수 있다. 객체에 대해 미리 서명된 URL을 만들 때 보안 자격 증명을 제공하고 버킷 이름, 객체 키, HTTP 메서드(GET으로 객체 다운로드) 및 만료 날짜와 시간을 지정해야 한다. 

더 자세한 내용은 공식문서를 참고하자.

+) presigined-url을 사용하지 않으려면 업로드할 때 public read 권한을 주는 방법이 있다. 업로드한 객체를 누구나 액세스하도록 설정함으로써 접근시 자격 증명이 필요없어진다.

 

[ ProductController ]

AWS의 S3를 사용하면 url을 통해 이미지 접근이 가능하기 때문에 프론트 단으로 링크만 넘겨줘도 괜찮다.

하지만 기존 코드에서 수정을 최대한 적게하기 위해서 링크를 보내지 않고, S3 저장소에서 파일을 읽어서 브라우저로 보내는 방법을 유지했다.

// image data transmit
@GetMapping("/display")
@ResponseBody
public ResponseEntity<byte[]> getFile(String fileName){
  log.info("fileName: "+ fileName);
  ResponseEntity<byte[]> result = null;
  try {
    HttpHeaders header = new HttpHeaders();

    // read from S3
    URL url = new URL(s3service.getFileURL(fileName));
    HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
    InputStream fileIS = urlConn.getInputStream();

    // MIME regardless of extention
    header.add("Content-Type", URLConnection.guessContentTypeFromStream(fileIS));
    
    result = new ResponseEntity<>(IOUtils.toByteArray(fileIS), header, HttpStatus.OK);
  
  } catch(IOException e) {
  	log.info("wrong file path");
  }
  return result;
}

URLConnection 

 : 웹을 통해 데이터를 주고 받는데 사용된다. (RFC 2616을 따른다.)

URLConnection 클래스는 추상 클래스이기 때문에 단독적으로 객체를 생성할 수 없다. 따라서 URL 클래스의 객체를 생성한 다음에 URL 클래스의 openConnection() 메서드를 이용해서 객체 를 생성해야한다. URL 클래스의 openConnection()을 호출하게 되면, URL 클래스가 사용하는 프로토콜에 따라 URLConnection을 상속한 알맞은 하위 클래스의 인스턴스를 얻게 된다. 예를 들어, HTTP 프로토콜을 사용할 경우 openConnection() 메소드는 HttpURLConnection 클래스의 인스턴스를 반환한다.

 

header.add("Content-Type", String );

 byte로 이미지 파일 데이터를 전송하면 MIME 타입이 파일의 종류에 따라 달라질 수 있는데, 이 부분을 해결하기 위해 probeContentType으로 적절한 MIME 타입 데이터를 헤더에 포함할 수 있다.

 

 

 

 

 

S3에서 이미지를 잘 가져오는 것을 확인

 

 

참고 출처 : 

 

offbyone.tistory.com/330

 

자바(Java)로 파일의 마임 타입(MIME Type) 확인하기

파일 다운로드를 구현할때 파일에 직접 링크를 하지 않고, 프로그램을 사용해서 웹루트 밖의 저장소에서 파일을 읽어서 브라우저로 보내야 하는 경우가 많이 있습니다. 이때 파일의 마임 타입(M

offbyone.tistory.com