
우선 s3에 업로드 하기 위해서는 권한을 가진 유저를 만들어줘야 한다.
IAM > 사용자 > 사용자 추가에 들어간다.
implementation 'io.awspring.cloud:spring-cloud-starter-aws:2.4.4'
package org.delivery.storeadmin.config;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@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
public AmazonS3 s3Client() {
AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
return AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.withRegion(region).build();
}
}
private String uploadImage(MultipartFile image, String folderName) {
// folderName : s3 버킷 안에 폴더를 지정할 때 사용함
this.validateImageFileExtention(image.getOriginalFilename());
try {
return this.uploadImageToS3(image, folderName);
} catch (IOException e) {
throw new IllegalArgumentException("파일 없음");
}
}
private void validateImageFileExtention(String filename) {
int lastDotIndex = filename.lastIndexOf(".");
if (lastDotIndex == -1) {
throw new IllegalArgumentException("확장자 없음");
}
String extention = filename.substring(lastDotIndex + 1).toLowerCase();
List<String> allowedExtentionList = Arrays.asList("jpg", "jpeg", "png");
if (!allowedExtentionList.contains(extention)) {
throw new IllegalArgumentException("지원하지 않는 확장자");
}
}
private String uploadImageToS3(MultipartFile image, String folderName) throws IOException {
String originalFilename = image.getOriginalFilename(); //원본 파일 명
String extention = originalFilename.substring(originalFilename.lastIndexOf(".")); //확장자 명
String s3FileName = folderName+"/"+UUID.randomUUID().toString().substring(0, 10) + originalFilename; //변경된 파일 명
InputStream is = image.getInputStream();
byte[] bytes = IOUtils.toByteArray(is);
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType("image/jpeg");
metadata.setContentLength(bytes.length);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
try{
PutObjectRequest putObjectRequest =
new PutObjectRequest(bucketName, s3FileName, byteArrayInputStream, metadata)
.withCannedAcl(CannedAccessControlList.PublicRead);
amazonS3Client.putObject(putObjectRequest);
}catch (Exception e){
log.error("s3 error {}",e.getMessage());
throw new IllegalArgumentException("s3 업로드 오류");
}finally {
byteArrayInputStream.close();
is.close();
}
return amazonS3Client.getUrl(bucketName, s3FileName).toString();
}
html 파일에서 아래와 같이 표현하면 이미지를 확인할 수 있다.
<a href="https://{bucket-name}.s3.{region-name}.amazonaws.com/{파일명}">사진보기</a>
단 이 경우 S3에 올라간 파일의 Content-Type 이 "image/jpeg" 여야한다. "image/*" 인 경우 다운로드 받아버린다.
