1️⃣ 화이트 리스트 확장자만 파일 업로드 허용


<aside> 📝 - 게시글 작성 API에 룰 기반 파일 업로드 적용

</aside>

⌨ 코드 : 서비스 계층

@RestController
@RequestMapping("posts")
@RequiredArgsConstructor
public class PostController {

    private final PostService postService;

    /**
     *** 6. 게시글 작성 API**
     * [POST] /posts/:userId
     * @return BaseResponse()
     */
    @PostMapping("/{userIdx}")     
    public BasicResponse createProduct(@PathVariable("userIdx") Long userIdx,
                                       @RequestPart(value = "content", required = false) String content,
                                       @RequestPart(value = "imageNumberlist", required = false) List<Integer> imageNumberlist,
                                       @RequestPart(value = "multipartFile", required = false) List<MultipartFile> multipartFile) {

        **/* 유효성 검사 구현부 */**
        if(content == null || content.length() > 1000){
            return new BasicResponse(REQ_ERROR_INVALID_POSTS_CONTENT);
        }
        if(imageNumber == null || imageNumber.size() > 10 ){
            return new BasicResponse(REQ_ERROR_INVALID_POSTS_IMAGE_NUMBER);
        }
        if(multipartFile.isEmpty() || multipartFile.size() > 10) {
            return new BasicResponse(REQ_ERROR_INVALID_POSTS_IMAGE_FILE);
        }
        if(imageNumber.size() != multipartFile.size() ) {
            return new BasicResponse(REQ_ERROR_DIFFERENT_SIZE_IMAGE_FILE_AND_IMAGE_NUMBER);
        }

        for(int i=0; i<multipartFile.size(); i++){
            String fileExt = multipartFile.get(i).getOriginalFilename().substring(multipartFile.get(i).getOriginalFilename().lastIndexOf(".")+1).toLowerCase();

            **//이미지 파일의 확장자가 git, jpg, jpeg, png가 아니면 예외 발생**
            if(! "gif".equals(fileExt) && ! "jpg".equals(fileExt) && ! "jpeg".equals(fileExt) && ! "png".equals(fileExt)){
                return new BasicResponse(REQ_ERROR_INVALID_POSTS_IMAGE_FILE_EXTENSION);
            }

            //이미지 파일 크기 제한 (10MB)
            if(multipartFile.get(i).getSize() > 10485760){
                return new BasicResponse(REQ_ERROR_INVALID_POSTS_IMAGE_FILE_SIZE);
            }
        }
        /* 유효성 검사 구현 끝 */

        try {
            //DB에 게시글 등록
            String responseMessage = postService.createProduct(userIdx, content, imageNumberlist, multipartFile);

            return new BasicResponse(responseMessage);
        } catch (BasicException exception) {
            return new BasicResponse(exception.getStatus());
        }
    }
}

🖥️ API 실행 결과

Untitled

2️⃣ UUID를 적용해 파일명 중복 방지


<aside> 📝 - 이미지 파일명에 UUID v4를 적용해 파일명 중복 방지

</aside>

⌨ 코드 : 서비스 계층

@Service
@RequiredArgsConstructor
public class PostService {

    private final PostDao postDao;
    private final PostImageDao postImageDao;
    private final UserDao userDao;
		private final AwsS3Service awsS3Service;

    **/* 6. 게시글 작성 */**
    @Transactional(rollbackFor = {Exception.class})
    public String createProduct(Long userIdX, String content, List<Integer> imageNumberlist, List<MultipartFile> multipartFile ) throws BasicException {

        //DB에 게시글 등록 (내용 ,이미지, 이미지 번호)
        try{
            User Writer = userDao.findByIdx(userIdX);

            //post DB에 저장 (생략)
****
            //postImage DB에 저장
****            List<PostImage> postImageListCreation = new ArrayList<>();
						List<String> UUID_fileNameList = new ArrayList<>();;

            for(int i=0; i<imageNumber.size(); i++){

								//UUID가 적용된 이미지 파일명 리턴
                UUID_fileNameList.add(awsS3Service.createFileNameToDB(multipartFile.get(i)));            //UUID.randomUUID().toString() + "-" + multipartFile.get(i).getOriginalFilename();   //이미지 파일명에 UUID 적용
                
								PostImage postImageCreation = PostImage.builder()
                        .image(Secret.AWS_S3_CONNECT_URL+UUID_fileNameList.get(i))
                        .imageNumber(imageNumberlist.get(i))
                        .post(postCreation)
                        .build();

                postImageListCreation.add(postImageCreation);
            }

            postImageDao.saveAll(postImageListCreation);
            return "게시글 등록 성공";

        } catch (Exception exception) {
            throw new BasicException(DATABASE_ERROR_CREATE_POST);  //게시글 등록 실패
        }
    }
}
@Service
@RequiredArgsConstructor
public class AwsS3Service {

    **//UUID를 포함하는 이미지 파일명 리턴**
    public String createFileNameToDB(MultipartFile imageFile) {

				String UUID_fileName = UUID.randomUUID().toString() + "." + fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase(); //UUID+파일 확장자
        return UUID_fileName;  //UUID 파일명 리턴
    }

}