매일 조금씩

[스프링] 파일 삭제 기능 recursive 구현 JPA 사용 본문

Spring Framework

[스프링] 파일 삭제 기능 recursive 구현 JPA 사용

mezo 2021. 12. 22. 18:05
728x90
반응형

백엔드에서 업로드한 파일을 삭제하는 기능을 구현하려면,

서버에서 저장된 것과 DB에 저장된 걸 두개다 삭제해야한다.

 

여기서 DB의 메타 하나를 삭제하는건 문제가 되지않는다. 

실제 물리파일이 아니기 때문에 delete쿼리로 쉽게 삭제가 되기 때문이다.

하지만, 실제 물리파일이 저장된 폴더를 삭제하는 것이 문제가 된다.

한번에 삭제 되지않고, 폴더가 비어있어야 삭제가 되기때문이다.

 

현재 서비스에서 물리파일은 서버에 다음 경로로 저장되어 있다. 

***  (파일/폴더명) 폴더  파일   ***

(파일 메타 pk) > (원본 pdf 파일명)

                           > image          >  (페이지번호).png

                           > thumbnail > (페이지번호).png

 

그래서 image, thumbnail폴더에 저장된 png 파일들을 모두 삭제한후 image, thumbnail 폴더를 삭제하고,

원본파일을 삭제해야 가장 상위 폴더를 삭제할 수 있다. 

 

더 자세한 설명은 Service 코드를 보며 설명하도록 한다. 

 

1. Controller

@DeleteMapping(value = "/{document_id}")
@ResponseBody
public ResponseEntity<String> deleteDocument(@PathVariable("document_id") long id)
    throws IOException {
  try{
    return docService.deleteDocument(id);
  } catch(EmptyResultDataAccessException e){
    return new ResponseEntity<>("directory is not found", HttpStatus.NOT_FOUND);
  }
}

 

 

2. Service

@Override
public ResponseEntity<String> deleteDocument(Long documentId)
    throws EmptyResultDataAccessException, IOException {
  documentRepository.deleteById(documentId);
  DirectoryUtil directoryUtil = new DirectoryUtil(documentId);

  if (FileSystemUtils.deleteRecursively(new File(directoryUtil.getDirectoryPath()))) {
    return new ResponseEntity<>("ok", HttpStatus.OK);
  } else {
    return new ResponseEntity<>("server error", HttpStatus.INTERNAL_SERVER_ERROR);
  }
}

맨위에 설명한 것처럼 delete()는 폴더가 비어있지 않으면 삭제가 되지않기 때문에 폴더를 비우는 작업을 해야한다.

recursive하게 직접 구현하는 방법도 있지만

Spring에선 FileSystemUtils라는 디렉토리에서 deleteRecursively(File directory) 라는 메서드를 지원하고 있기 때문에

위 코드처럼 if 문 안의 아래 한줄이면 디렉토리를 지우는 것이 가능하다.

FileSystemUtils.deleteRecursively(new File(directoryUtil.getDirectoryPath()))

 

 

3. Repository

@Repository
public interface DocumentRepository extends JpaRepository<Document, Long>{
  void deleteById(Long documentId);
}

 

728x90
반응형