파일 업로드(하나 업로드 vs 여러 개 업로드)
by 볼빵빵오춘기엔티티 클래스
※ 해당 프로젝트에서는 총 3개의 게시판에서 파일을 업로드 가능하기에 어느 게시판에서 저장했는지 알고자 board, boardId 를 필드를 정의했다.
@Entity @Data @Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder @Table(name = "DA_BoardFile") public class BoardFileEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; // pk private String board; // 어떤 board에서 가져왔는지 // 게시판의 pk 저장 // 어노테이션을 이용하여 연관관계를 맺지않음 // why? board table에 community BBS 말고도 다른 BBS의 파일도 저장할 것이기 때문이다. private int boardId; // board pk private String originalFileName; // 원본 파일 이름 private String storedFileName; // 저장 파일 이름 @CreationTimestamp @Column(updatable = false) private LocalDateTime createDate; // 작성시간 @UpdateTimestamp private LocalDateTime updatedDate; }
서비스 클래스
//한 개의 파일을 받을 때 public void save(CommunityDto communityDto,MultipartFile file) throws Exception{ // 파라미터로 받아온 dto를 entity로 변환 CommunityEntity communityEntity = CommunityEntity.toSaveCommnunityEntity(communityDto); // 파일이 하나 일 경우 if(file !=null && !file.isEmpty()){ // 파일이 있을 경우 communityEntity.setFileAttached(1); CommunityEntity saveEntitiy = commnunityRepository.save(communityEntity); // 파일 이름가져오기 String originalFileName = file.getOriginalFilename(); // 저장용 파일 이름 만들기 UUID uuid = UUID.randomUUID(); String storedFileName = System.currentTimeMillis()+"-"+uuid; // boardFile DB에 넣을 BoardFileEntity 세팅 BoardFileEntity boardFileEntity = new BoardFileEntity(); boardFileEntity.setBoardId(saveEntitiy.getId()); boardFileEntity.setOriginalFileName(originalFileName); boardFileEntity.setStoredFileName(storedFileName); // 파일 저장용 폴더 String savePath = System.getProperty("user.dir")+"/src/main/resources/static/files/community"; // 파일 저장 File saveFile = new File(savePath,storedFileName); file.transferTo(saveFile); // boardFile DB에 넣음 boardFileRepository.save(boardFileEntity); }else{ // 파일이 없을 경우 communityEntity.setFileAttached(0); commnunityRepository.save(communityEntity); } }
// 여러 개의 파일을 가져올 경우 public void save(CommunityDto communityDto, List<MultipartFile> files) throws Exception{ CommunityEntity communityEntity = CommunityEntity.toSaveCommnunityEntity(communityDto); if(files!=null){ // 파일이 있을 경우 communityEntity.setFileAttached(1); CommunityEntity saveEntitiy = commnunityRepository.save(communityEntity); // 파일 이름가져오기 for(MultipartFile file : files){ // 원본 이름 String originalFileName = file.getOriginalFilename(); // 확장자 가져오기 String[] extension = originalFileName.split("[.]"); int lastIdx = extension.length-1; // 저장용 파일 이름 만들기 UUID uuid = UUID.randomUUID(); String storedFileName = System.currentTimeMillis()+"-"+uuid+"."+extension[lastIdx]; // boardFile DB에 넣을 BoardFileEntity 세팅 BoardFileEntity boardFileEntity = new BoardFileEntity(); boardFileEntity.setBoardId(saveEntitiy.getId()); boardFileEntity.setOriginalFileName(originalFileName); boardFileEntity.setStoredFileName(storedFileName); boardFileEntity.setBoard("community"); // 파일 저장용 폴더 String savePath = System.getProperty("user.dir")+"/src/main/resources/static/img/community"; // 파일 저장 File saveFile = new File(savePath,storedFileName); file.transferTo(saveFile); // boardFile DB에 넣음 boardFileRepository.save(boardFileEntity); } }else{ // 파일이 없을 경우 communityEntity.setFileAttached(0); commnunityRepository.save(communityEntity); } }
정리
- 파일을 하나만 가져올 경우에는 파일 그대로 가져오면 되지만 여러 개 가져올 때는 List에 담아서 가져오면 된다.
- 파일을 가져올 경우에는 메소드에 throws Exception 을 넣어주어야 한다.
🧐 why? 파일 처리와 관련된 작업에서는 다양한 종류의 예외가 발생할 수 있다. 따라서 이를 명시적으로 처리하거나 호출자에게 전달하여 적절한 예외 처리를 할 수 있도록 하기위함이다.
🧐 파일 업로드 시 예외 처리 흐름(더보기 참고)
더보기
- Controller에서 파일 수신
FileController 클래스에서 파일을 받아온다.
만약 파일을 받아오는 과정에서 예외가 발생할 경우, throws Exception으로 명시되어 있어 해당 예외가 호출자에게 전달된다. - Service에서 파일 저장
FileService 클래스에서 파일을 저장한다.
이 과정에서 파일이 비어 있거나 파일 시스템 오류 등으로 인해 예외가 발생할 수 있다. saveFile 메소드가 throws IOException으로 명시되어 있어, 발생한 예외가 FileController 클래스의 uploadFile 메소드로 전달된다. - 예외 전파 및 처리
FileController의 uploadFile 메소드가 throws Exception으로 선언되어 있으므로, 발생한 예외는 호출자 (여기서는 Spring 프레임워크)에게 전파된다.
Spring은 전파된 예외를 처리하여 클라이언트에게 적절한 에러 메시지를 반환한다.

블로그의 정보
Hello 춘기's world
볼빵빵오춘기