
기존에는 MultipartFile을 파일로 저장을시킨후에 업로드를 하고 삭제하는 방식으로 진행을 하였습니다.
하지만 첫번째장을 썸네일로 만드는 작업을 하려고하면 잘 안되는 문제가 발생을 하여서 file저장 방식이 아닌 bufferimage로 받아서 파이프라인을 타게끔 변경을 하였습니다.
기존 방법이 궁금하신분은 이 곳을 보고 와주세요.
먼저 껀쮸롤러를 먼저 보겠습니다.
@PostMapping
public ResponseEntity<SingleResult<ProductResponse>> createProduct(
@RequestHeader("Authorization") String accessToken,
@RequestPart(value = "file") List<MultipartFile> multipartFile,
@RequestPart(value = "product") @Valid ProductRequest productRequest, BindingResult bindingResult) throws IOException {
productService.validateUploadForm(bindingResult);
productService.validateFileExists(multipartFile);
String[] splitToken = accessToken.split(" ");
ProductResponse productResponse = productService.createProduct(splitToken[1], productRequest, multipartFile);
return new ResponseEntity<>(responseService.getSingleResult
(productResponse), HttpStatus.CREATED);
}
productservice 에서 등록을 해주는 기능을 실행을 해줍니다.
써비스를 보겠습니다.
public ProductResponse createProduct(String accessToken,
ProductRequest productRequest,
List<MultipartFile> multipartFile) throws IOException {
Account account = accountService.findAccountByAccessToken(accessToken);
String thumbNailUrl = uploadService.makeThumbNail(multipartFile.get(0));
List<String> uploadImagesUrl = uploadService.uploadImages(multipartFile);
Product product = productRequest.toProduct(account, uploadImagesUrl, thumbNailUrl);
productRepository.save(product);
return ProductResponse.toProductResponse(product, account);
}
먼저 아거 로직인 토큰 검증을 해준다음 썸네일이터로 첫번째 장을 썸네일로만들어 주고
들어온 파일들을 for문을 돌려서 순차적으로 업로드 시켜줍니다.
이제 핵심 로직을 보겠습니다.
public String uploadImg(MultipartFile multipartFile) throws IOException {
String origName = multipartFile.getOriginalFilename();
final String ext = origName.substring(origName.lastIndexOf('.'));
if (ext.equals(".jpg") || ext.equals(".png") || ext.equals(".jpeg")) {
final String saveFileName = getUuid() + ext;
BufferedImage image = ImageIO.read(multipartFile.getInputStream());
return uploadImgToS3(image, saveFileName, ext);
} else throw new InvaildFileExtensionException();
}
먼저 일단 혹시 모르니 확장자를 걸러주고 그다음 Bufferimage로 읽어 오겠습니다.
그다음 uploadImgToS3에다가 이미지, 이름, 확장자를 던져줍니다.
public String uploadImgToS3(BufferedImage image, String Filename, String ext)
throws IllegalStateException, IOException {
String url;
try {
ByteArrayOutputStream os = new ByteArrayOutputStream();
log.info("확장자는 :{}", ext.substring(1));
ImageIO.write(image, ext.substring(1), os);
byte[] bytes = os.toByteArray();
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentLength(bytes.length);
objectMetadata.setContentType(ext.substring(1));
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
final TransferManager transferManager = new TransferManager(this.amazonS3Client);
final PutObjectRequest request = new PutObjectRequest(bucket, Filename, byteArrayInputStream, objectMetadata);
final Upload upload = transferManager.upload(request);
upload.waitForCompletion();
} catch (AmazonServiceException | InterruptedException e) {
e.printStackTrace();
}
url = defaultUrl + Filename;
return url;
}
S3에서 제공하는 PutObjectRequest에서는 3가지 방식이 가능합니다.

이중에서 저는 가장 마지막 방법으로 inputStream형식으로 보내는 방식을 선택하였습니다.
요로코롬 버킷과 키 inputstream 메타데이터를 넣어주면 스무스 하게 프론트에서 넘어온 데이터가 쭈르르륵 s3로 흘러들어가는 기능을 구현을 할수 있습니다.
다음에는 사용자에게 이미지를 더 빨리 로드를 하기위해서 AWS에 Cloudfront서비스를 적용시키는 포스팅으로 돌아오겠습니다.
'Spring Boot > A-ger프로젝트 탄생의비화' 카테고리의 다른 글
보고도 믿지못한 카카오 API호출 4만6천번.. (0) | 2022.01.18 |
---|---|
상품 조회 중에 만난 N+1문제 (0) | 2022.01.18 |
Spring boot 에서 AWS S3 버킷 업로드 파일 확장자 구분해서 업로드 해주기 (0) | 2022.01.17 |
spring-boot 프론트엔드와 무한 스크롤 구현 하기[ep.2] (0) | 2022.01.17 |
spring-boot 프론트엔드와 무한 스크롤 구현 하기[ep.1] (0) | 2022.01.17 |