파일 업로드(하나 업로드 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은 전파된 예외를 처리하여 클라이언트에게 적절한 에러 메시지를 반환한다.
'👩🏻💻 About 프로그래밍 > spring' 카테고리의 다른 글
회원가입 유효성 검사 (0) | 2024.08.13 |
---|---|
Spring Security 로그인 실패 시 에러메세지 (0) | 2024.08.12 |
JPA 동적쿼리 사용해보기 (0) | 2024.07.19 |
JPA 정적쿼리, 동적쿼리(feat. JpaSpecificationExecutor) (0) | 2024.07.19 |
JPA 반환타입 (0) | 2024.07.18 |
블로그의 정보
Hello 춘기's world
볼빵빵오춘기