JAVA와 AWS S3와 연동

JAVA와 AWS S3와 연동하기 위해서 Java용 AWS SDK를 다운 받는다.

AWS SDK Java jar pom.xml에 추가

1
2
3
4
5
6
<!-- AWS SDK Java -->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.11.66</version>
</dependency>

AWS S3 파일 업로드 하기

실제로 S3에 업로드 하기 위해서 S3에 권한이 필요합니다. 권한을 갖고 있는 ACCESS_KEY, SECRET_KEY를 변수에 저장하고, 사용할 BUCKET_NAME도 변수에 저장한다.

1
2
3
private static String BUCKET_NAME = "BUCKET_NAME";
private static String ACCESS_KEY = "ACCESS_KEY";
private static String SECRET_KEY = "SECRET_KEY";

이미지 업로드 메서드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public static String imageBoardUpload(MultipartFile attach, String savedFileName) {
AmazonS3 amazonS3; //인스턴스를 초기화 시킨다.

// 인증 객체를 생성한다.
AWSCredentials awsCredentials = new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY);
amazonS3 = new AmazonS3Client(awsCredentials);

// 파일 metadata 설정
ObjectMetadata omd = new ObjectMetadata();
omd.setContentType(attach.getContentType());
omd.setContentLength(attach.getSize());

// 실제 업로드 기능을 수행
PutObjectRequest putObjectRequest;
try {
putObjectRequest = new PutObjectRequest(BUCKET_NAME, savedFileName, attach.getInputStream(), omd);
amazonS3.putObject(putObjectRequest);

} catch (IOException e) {
e.printStackTrace();
return "fail";
}
return "success";
}

attach로 s3에 올릴 이미지 파일을 받아오고, savedFileName으로 s3에 저장될 파일이름을 받아온다. return을 String으로 받은 이유는 controller에서 s3에 업로드가 성공이면 DB에등록이되고, 실패면 DB에 등록이 되지 않도록 하기 위해서이다.

putObjectRequest = new PutObjectRequest(BUCKET_NAME, savedFileName, attach.getInputStream(), omd);

PutObjectRequest(저장할 디렉토리, 저장될 이름, inputStream 데이터, 설정해준 메타데이터);

metadata 사용하는 이유? contentType, size설정 이유?

metadata는 그 데이터에 대한 정보를 알려준다. 파일의 정보들을 메타데이터에 저장을 해주면 그 정보에 맞는 데이터를 더 빠르고 쉽게 찾을 수 있다.

위 코드에서 metadata는 S3에 이 파일에 대해 어떻게 읽어야하고 어떤 사이즈 인지, 이 파일에 대한 정보를 전해주기 위해 메타데이터를 설정해줍니다.

이미지 다운로드 메서드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public static ResponseEntity<byte[]> imageDownload(String key, String fileName) throws IOException {
AmazonS3 amazonS3; //인스턴스를 초기화 시킨다.

// 인증 객체를 생성한다.
AWSCredentials awsCredentials = new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY);
amazonS3 = new AmazonS3Client(awsCredentials);

// 실제 다운로드 기능을 수행
GetObjectRequest getObjectRequest;
getObjectRequest = new GetObjectRequest(BUCKET_NAME, key);
S3Object o = amazonS3.getObject(getObjectRequest);
S3ObjectInputStream objectInputStream = o.getObjectContent();

byte[] bytes = IOUtils.toByteArray(objectInputStream);
// HTTP 응답 헤더 정보를 유지하는 HttpHeaders 오브젝트
// ResponseEntity 오브젝트를 사용함으로 개별적 헤더를 설정 할 수 있다.
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.parseMediaTypes(o.getObjectMetadata().getContentType()).get(0));
httpHeaders.setContentLength(bytes.length);
httpHeaders.setContentDispositionFormData("attachment", fileName);

return new ResponseEntity<>(bytes, httpHeaders, HttpStatus.OK);
}

key로 S3에 저장되어 있는 파일 이름을 받아오고, fileName으로 다운로드 받을 때 저장될 이름을 받아온다.

ResponseEntity<>

독립적인 RestFul API를 개발하기 위해 , 상태코드, HttpHeader, 응답메시지, 반환 데이터를 모두 지정해서 반환해주기 위해 사용한다. 서버에서는 Client에서 데이터를 어떻게 출력하는 방식에 대해 관심을 갖지 않고 오직 리소스를 전달해주는 것에만 관심이 있다.

ResponseEntity<byte[]>(byte[] body, MultiValueMap<String, String> headers, HttpStatus status)