Hello

파일 업로드(하나 업로드 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

볼빵빵오춘기

활동하기