[Spring] S3 파일 업로드

S3 정보 세팅

# AWS Account Credentials (AWS 접근 키)
cloud.aws.credentials.accessKey={엑세스 키}
cloud.aws.credentials.secretKey={시크릿 키}

# AWS S3 bucket Info (S3 버킷정보)
cloud.aws.s3.bucket={버킷 이름}
cloud.aws.region.static={리전 정보}
cloud.aws.stack.auto=false

# file upload max size (파일 업로드 크기 설정)
spring.servlet.multipart.max-file-size=20MB
spring.servlet.multipart.max-request-size=20MB

 

S3 Client 설정

@Configuration 
public class AwsS3Config {

    @Value("${cloud.aws.region.static}")
    private String awsRegion;

    @Value("${cloud.aws.credentials.accessKey}")
    private String awsAccessKey;

    @Value("${cloud.aws.credentials.secretKey}")
    private String awsSecretKey;

    @Bean
    public S3Client s3Client() {
        AwsCredentials credentials = AwsBasicCredentials.create(awsAccessKey, awsSecretKey);

        return S3Client.builder()
                .region(Region.of(awsRegion))
                .credentialsProvider(() -> credentials)
                .build();
    }
}

 

파일 이름 저장 방식

public class CommonUtils {
	private static final String FILE_EXTENSION_SEPARATOR = ".";

	public static String buildFileName(String originalFileName) {
	    int fileExtensionIndex = originalFileName.lastIndexOf(FILE_EXTENSION_SEPARATOR);
	    String fileExtension = originalFileName.substring(fileExtensionIndex);
	    String fileName = originalFileName.substring(0, fileExtensionIndex);
	    String now = String.valueOf(System.currentTimeMillis());

	    return fileName + now + fileExtension;
	  }
}

 

S3 파일 업로드 로직

Multipart로 파일을 받아서 S3에 업로드 후 Url 반환

@RequiredArgsConstructor
@Service
public class AwsS3Service {

    private final S3Client s3Client;

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

    public String uploadFileV1(MultipartFile multipartFile) throws FileUploadException, FileNotFoundException {
        // 업로드된 파일이 비어 있는지 확인
        if (multipartFile.isEmpty()) {
            throw new FileNotFoundException("업로드된 파일이 비어 있습니다.");
        }

        String fileName = CommonUtils.buildFileName(multipartFile.getOriginalFilename());

        try (InputStream inputStream = multipartFile.getInputStream()) {
            // 파일 데이터를 바이트 배열로 변환
            byte[] fileBytes = inputStream.readAllBytes();

            // S3에 파일 업로드
            s3Client.putObject(PutObjectRequest.builder()
                    .bucket(bucketName)
                    .key(fileName)
                    .contentType(multipartFile.getContentType()) // 컨텐츠 유형 (옵션)
                    .build(), RequestBody.fromBytes(fileBytes));

            // 파일 업로드 완료 후, 업로드된 파일의 URL 등을 반환 (예를 들면 S3에 업로드한 파일의 URL을 반환)
            String fileUrl = s3Client.utilities().getUrl(builder -> builder.bucket(bucketName).key(fileName)).toExternalForm();
            return fileUrl;
            
        } catch (IOException | S3Exception e) {
            throw new FileUploadException("파일 처리 중 오류 발생: " + e.getMessage());
        }
    }
  }

 

Controller

   @PostMapping("/upload")
   public void uploadFile(
      @RequestPart(value = "file") MultipartFile multipartFile) throws FileUploadException, FileNotFoundException {
	  System.out.println(multipartFile.getOriginalFilename());	//받아온 파일 이름 test용
	  System.out.println(awsS3Service.uploadFileV1(multipartFile));	//S3에 저장한 이미지 url 값
   }

'개발 > Spring' 카테고리의 다른 글

[JPA] Dirty check, @Transactional, Auditing  (0) 2023.07.28
[JPA] ORM, JPA, Hibernate  (0) 2023.07.28
[Build] Maven, Gradle 빌드  (0) 2023.07.20
[Spring] Static 객체와 Bean의 차이  (2) 2023.06.28
[Spring] Filter & Interceptor & AOP  (0) 2023.05.29