일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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
- 코드스테이츠 합격 후기
- 코드스테이츠 백엔드 후기
- codestates 국비지원 1기 합격 후기
- 금감원
- 코드 스테이츠 백엔드 교육과정
- 백내장 다초점렌즈 삽입술
- 겜스고
- 금감원 백내장 민원
- 코드스테이츠 백엔드 부트캠프 합격
- CodeState 후기
- Java
- 백준 알고리즘
- 금융감독원 민원신청
- 자바
- 코테 합격후기
- 메서드
- 코드스테이츠 부트캠프
- 금융감독원
- 코드스테이츠 부트캠프 합격 후기
- Code States 백엔드 합격 후기
- Gamsgo
- 에이치엘비
- HLB
- 백내장 금감원
- 해시
- 코드스테이츠 백엔드 교육과정
- 보험금 지급거절
- Spring
- 코드스테이츠 합격
- 백내장
Archives
- Today
- Total
개발하는 동그리
[Main Project] AWS S3 사진 업로드 설정 본문
반응형
Application.yml
spring:
servlet:
multipart:
max-file-size: 20MB
max-request-size: 20MB
h2:
console:
enabled: true
path: /h2
datasource:
url: jdbc:h2:mem:test
username:
password:
driver-class-name: org.h2.Driver
jpa:
hibernate:
ddl-auto: create # (1) ??? ?? ??
show-sql: true # (2) SQL ?? ??
properties:
hibernate:
format_sql: true # (3) SQL pretty print
logging:
level:
org:
springframework:
orm:
jpa: DEBUG
cloud:
aws:
credentials:
accessKey: { }
secretKey: { }
s3:
bucket: { bucket name }
region:
static: "ap-northeast-2"
stack:
auto: false
AWSConfig
@Configuration
public class AWSConfig {
@Value("${cloud.aws.credentials.accessKey}")
private String accessKey;
@Value("${cloud.aws.credentials.secretKey}")
private String accessSecret;
@Value("${cloud.aws.region.static}")
private String region;
@Bean
public AmazonS3 s3Client() {
AWSCredentials credentials = new BasicAWSCredentials(accessKey, accessSecret);
return AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.withRegion(region).build();
}
}
AwsS3Service
@Transactional
@RequiredArgsConstructor
@Slf4j
@Service
public class AwsS3Service {
private final AmazonS3Client amazonS3Client;
private final ReviewImgRepository reviewImgRepository;
@Value("${cloud.aws.s3.bucket}")
private String bucketName;
/**
* 단일 파일 업로드
*/
public String singleUploadFile(MultipartFile multipartFile) {
validateFileExists(multipartFile);
String fileName = originalFileName(multipartFile);
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentType(multipartFile.getContentType());
try (InputStream inputStream = multipartFile.getInputStream()) {
amazonS3Client.putObject(new PutObjectRequest
(bucketName, fileName, inputStream, objectMetadata)
.withCannedAcl(CannedAccessControlList.PublicRead));
} catch (IOException e) {
log.error("Can Not Upload Image..!", e);
throw new RuntimeException();
}
return amazonS3Client.getUrl(bucketName, fileName).toString();
}
//s3로 파일 업로드 하고 url 리턴하는 메서드
public String uploadFile(MultipartFile multipartFile) throws IOException {
validateFileExists(multipartFile);
String fileName = originalFileName(multipartFile);
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentType(multipartFile.getContentType());
try (InputStream inputStream = multipartFile.getInputStream()) {
byte[] bytes = IOUtils.toByteArray(inputStream);
objectMetadata.setContentLength(bytes.length);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
amazonS3Client.putObject(new PutObjectRequest
(bucketName, fileName, byteArrayInputStream, objectMetadata)
.withCannedAcl(CannedAccessControlList.PublicRead));
} catch (Exception e) {
log.error("Can not upload image, ", e);
throw new FileUploadException();
}
String url = amazonS3Client.getUrl(bucketName, fileName).toString();
return url;
}
//파일 이름 추출하는 메서드
public String originalFileName(MultipartFile multipartFile) {
try {
return CommonUtils.buildFileName(multipartFile.getOriginalFilename());
} catch (Exception e) {
log.error("Can not filename, ", e);
return "filename";
}
}
// review 이미지 업로드
public List<ReviewImg> convertReviewImg(List<MultipartFile> multipartFileList) {
if (multipartFileList.size() > 3) throw new RuntimeException("사진 파일 갯수 초과");
List<ReviewImg> fileList = new ArrayList<>();
multipartFileList.forEach(file -> {
String url;
try {
url = uploadFile(file);
} catch (IOException e) {
log.error("Can not upload, ", e);
throw new RuntimeException(e);
}
String fileName = originalFileName(file);
ReviewImg reviewImg = ReviewImg.builder()
.fileName(fileName)
.imgUrl(url)
.build();
reviewImgRepository.save(reviewImg);
fileList.add(reviewImg);
});
return fileList;
}
// review 이미지 업데이트
public List<ReviewImg> updateReviewImg
(List<ReviewImg> reviewImgList, List<MultipartFile> multipartFileList) {
if (multipartFileList.size() > 3) throw new RuntimeException("사진 파일 갯수 초과");
// 기존에 있있던 파일이름 불러오기
List<String> list = reviewImgList.stream()
.map(ReviewImg::getFileName).collect(Collectors.toList());
for (String file : list) {
if (!"".equals(file) && file != null) {
boolean isExistObject = amazonS3Client.doesObjectExist(bucketName, file);
// 파일이 있으면 삭제
if (isExistObject) amazonS3Client.deleteObject(bucketName, file);
}
}
// 삭제후 새로운 이미지 업로드
return convertReviewImg(multipartFileList);
}
//file 이름과 url 받아서 List<PostsImg> 로 리턴하는 메서드
public List<PostsImg> convertPostImg(List<MultipartFile> multipartFileList) {
if (multipartFileList.size() != 5) {
throw new RuntimeException("you need to upload 5 image");
}
List<PostsImg> fileList = new ArrayList<>();
multipartFileList.forEach(file -> {
String url;
try {
url = uploadFile(file);
} catch (IOException e) {
log.error("Can not upload, ", e);
throw new RuntimeException(e);
}
String fileName = originalFileName(file);
PostsImg postsImg = PostsImg.builder()
.fileName(fileName)
.imgUrl(url)
.build();
fileList.add(postsImg);
});
return fileList;
}
//List<PostsImg> 수정 메서드(기존 s3에 있는 파일 삭제 후 추가)
// s3에 기존 파일이 삭제되지 않는 에러가 있음 추후 수정 예정
public List<PostsImg> reviseFileV1(List<PostsImg> imgList
,List<MultipartFile> multipartFileList) {
List<String> list = imgList.stream().map(PostsImg::getFileName)
.collect(Collectors.toList());
for (int i = 0; i < list.size(); i++) { //기존 파일 삭제
String currentFilePath = list.get(i);
if (!"".equals(currentFilePath) && currentFilePath != null) {
boolean isExistObject =
amazonS3Client.doesObjectExist(bucketName, currentFilePath);
if (isExistObject) {
amazonS3Client.deleteObject(bucketName, currentFilePath);
}
}
}
return convertPostImg(multipartFileList);
}
//s3에 업로드 할 사진 validation 메서드
private void validateFileExists(MultipartFile multipartFile) {
if (multipartFile.isEmpty()) {
throw new RuntimeException("EmptyFileException()");
}
}
}
CommonUtils
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;
}
}
Controller Class
@PostMapping("/create")
public ResponseEntity createCard(@RequestPart(value = "dogCardDto") DogCardDto.Post dogCardDto,
@RequestPart(value = "file") MultipartFile file,
@AuthenticationPrincipal PrincipalDetails principalDetails) {
DogCard dogCard = mapper.dogDtoToDogCard(dogCardDto);
dogCardService.savedDogCard(dogCard, file, principalDetails.getUsers());
log.info("dogName = {}", dogCard.getDogName());
log.info("dogType = {}", dogCard.getType());
log.info("dogImageUrl = {}", dogCard.getPhotoImgUrl());
return new ResponseEntity<>(new SingleResponseDto<>("create success"), HttpStatus.CREATED);
}
AwsConfig, AwsS3Service, CommonUtils, application.yml 설정 완료 후
Controller Class 이미지 업로드 설정
@RequestPart(value = "file" ) MultipartFile file
이미지 파일과 동시에 json data를 올려야 할 때
@RequestPart(value = "dto") PostDto postDto와 같이 입력해주면 된다.
※ 주의할 점은 value 의 file & Multifile의 file의 값이 일치해야 한다.
반응형
'스테이츠 코드(백엔드) > Main Project' 카테고리의 다른 글
[Main Project] 게시글 좋아요 구현 (0) | 2022.09.29 |
---|---|
[Main Project] Spring Security + JWT 설정 (0) | 2022.09.29 |
[Main Project] @Convert : booleanToString (2) | 2022.09.29 |
[Main Project] 서비스 실시간 update (3) | 2022.09.27 |
[Main Project] 코드 작동 오류 ( 해결 ~ ) (7) | 2022.09.22 |