java, spring

[Spring] 잘못 업로드된 파일 삭제 1 [Quartz, cron, @EnableScheduling, @Scheduled]

isaac.kim 2021. 9. 4. 11:36
728x90
반응형

[Spring] 잘못 업로드된 파일 삭제 1 [Quartz, cron, @EnableScheduling, @Scheduled]

 

도움이 되셨다면 광고 한 번 클릭 부탁드립니다. 한 번의 클릭이 제게 큰 힘이 된답니다!^^

 

이전 글

2021.09.03 - [Spring] - [Spring] 게시물의 수정과 첨부파일

2021.08.30 - [Spring] - [Spring] 게시물의 삭제와 첨부파일 삭제

2021.08.30 - [Spring] - [Spring] 게시물의 조회와 첨부파일 보여주기

2021.08.29 - [Spring] - [Spring] 게시물에 첨부파일 등록하기 - 2 -

2021.08.29 - [Spring] - [Spring] 게시물에 첨부파일 등록하기 - 1 -

2021.08.28 - [Spring] - [Spring] 첨부파일 삭제

2021.08.28 - [Spring] - [Spring] 원본 이미지 보여주기

2021.08.27 - [Spring] - [Spring] 첨부파일 다운로드, IE/Edge 브라우저의 문제 해결

2021.08.26 - [Spring] - [Spring] 첨부파일의 다운로드

 

 

Ajax를 이용해 첨부파일을 사용하면 사용자가 게시물을 등록하거나 수정하기 전에 미리 업로드시킨 파일들을 볼 수 있다는 장점이 있지만, 문제가 있습니다.

 

반응형

 

1. 첨부파일만 등록하고 게시물을 등록하지 않았을 때의 문제 : 파일은 이미 서버에 업로드되었지만, 게시물을 등록하지 않았으므로 의미 없이 파일들만 서버에 업로드된 상황

 

2. 게시물을 수정할 때 파일을 삭제했지만 실제로 폴더에서 기존 파일은 삭제되지 않은 문제 - 데이터베이스에는 기존 파일이 삭제되었지만, 실제 폴더에는 남는 문제

 

위 상황의 공통적인 문제는 사용자가 Ajax로 어떤 작업을 한 후 비정상적으로 브라우저를 종료하거나 페이지를 빠져나가는 문제입니다. 이 문제를 해결하는 핵심은 정상적으로 사용자의 게시물에 첨부된 파일인지 아니면 사용자가 게시물을 수정할 때 업로드했지만 최종적으로 사용되는 파일인지 아닌지를 파악하는 것이 핵심입니다.

 

잘못 업로드된 파일의 정리

 

게시물에 포함된 첨부파일들의 정보는 데이터베이스에 저장됩니다. 위에서 설명된 상황에 의해 불필요한 파일들은 데이터베이스의 목록과 비교하여 찾을 수 있습니다. 

 

파일 목록을 찾을 때에는 오늘 날짜가 아닌 파일들을 대상으로 해야 합니다. 오늘 날짜를 대상으로 하는 경우 현재 게시물을 작성하거나 수정하기 위해 업로드하고 있는 파일들을 삭제할 가능성이 있기 때문입니다.

 

잘못 업로드된 파일 탐색

1. 어제 날짜로 등록된 첨부파일의 목록을 구하기

2. 어제 업로드가 되었지만, 데이터베이스에는 존재하지 않는 파일들 찾기

3. 데이터베이스와 비교해서 필요 없는 파일들 삭제하기

 

이 작업은 주기적으로 동작해야 하므로 스케줄링을 할 수 있는 Spring-Batch나 Quartz 라이브러리를 이용합니다.


Quartz 라이브러리 설정

 

Quartz 라이브러리는 일반적으로 스케줄러를 구성하기 위해 사용합니다. 서버에서 주기적으로 매일, 매주, 매월 등 주기적으로 특정한 프로그램을 실행할 필요가 있습니다. 이 작업은 운영체제의 기능을 이용해 작업할 수도 있지만, 스프링과 Quartz 라이브러리를 이용하면 간단히 처리할 수 있습니다.

 

pom.xml에 Quartz 라이브러리 추가

 

Quartz에 대한 설정은 XML과 어노테이션을 활용할 수 있습니다. 어노테이션을 이용하기 위해 root-context.xml의 일부를 수정합니다.

 

root-context.xml의 네임스페이스에 task 항목을 체크합니다.

root-context.xml에 <task:annotation-driven/>를 추가합니다. 'com.project.task' 패키지 스캔 태그를 추가합니다.

 

Java 설정을 이용하는 경우

어노테이션을 이용하는 스케줄러의 설정은 @EnableScheduling 설정을 통해서 이루어집니다. RootConfig 클래스 파일에는 com.project.task 패키지를 스캔하고 어노테이션을 추가합니다.

 

RootConfig 클래스

 


Task 작업의 처리

실제 작업의 로직은 'com.project.task'라는 패키지 내에 FileCheckTask라는 클래스를 작성해 처리합니다.

 

FileCheckTask 클래스에는 @component, @Scheduled 어노테이션이 사용됩니다. @Scheduled 어노테이션 내에는 cron이라는 속성을 부여해서 주기를 제어합니다. 로그가 정상적으로 기록되는지 확인하기 위해 log.warn( ) 레벨을 이용해 실행 중 확인할 수 있도록 합니다.

 

FileCheckTask는 스프링의 빈으로 설정합니다. 'com.project.task' 패키지 스캔 태그를 추가합니다.

root-context.xml

 

cron 설정은 위 경우 매분 0초마다 한 번씩 실행되도록 지정되었으므로, 서버를 실행해 두고 1분마다 로그가 기록되는지 확인합니다.

 

실행 확인

 

Java 설정을 이용하는 경우

어노테이션을 이용하는 스케줄러의 설정은 @EnableScheduling 설정을 통해서 이루어집니다. RootConfig 클래스 파일에는 com.project.task 패키지를 스캔하도록 지정합니다. @ComponentScan(basePackages = {"com.project.task"})

 

RootConfig 클래스

 


BoardAttachMapper 수정

FileCheckTask의 정상 동작 여부를 확인했다면 DB에서 어제 등록된 모든 파일의 목록이 필요하므로, BoardAttachMapper에 첨부파일 목록을 가져오는 메서드를 추가합니다.

 

BoardAttachMapper 인터페이스

 

다음은 전 날짜의 모든 파일을 불러오는 SQL을 테스트 하고, 해당 쿼리는 BoardAttachMapper.xml에 등록합니다.

SQL 날짜 처리 부분은 데이터베이스마다 다를 수 있습니다.

 

SQL 테스트

BoardAttachMapper.xml

테스트 코드 작성 후 JUnit으로 테스트 합니다.

 

'src/test/java' 폴더 아래

com.project.mapper.BoardAttachMapperTests 클래스

 

테스트 코드 실행결과


cron 설정과 삭제 처리

Cron은 원래 유닉스 계열에서 사용되는 스케줄러 프로그램의 이름이지만, 워낙 많이 사용되다 보니 각종 언어나 기술에 맞는 라이브러리 형태로 많이 사용됩니다.

 

FileCheckTask 내에서는 아래와 같이

표현식(붉은색 박스)이 사용되는데 의미는 '매분 0초가 될 때마다 실행한다'로 해석할 수 있습니다.

 

※ cron 표현식

● * : 모든 값을 뜻합니다. [모든 수]

● ? : 특정한 값이 없음을 뜻합니다. [제외]

● - : 범위를 뜻합니다. (예) 월요일에서 수요일까지는 MON-WED로 표현 [기간]

● , : 특별한 값일 때만 동작 (예) 월, 수, 금 MON, WED, FRI [특정 시간]

● / : 시작시간 / 단위  (예) 0분부터 매 5분 0/5 [시작 시간과 반복 시간]

● L : 일에서 사용하면 마지막 일, 요일에서는 마지막 요일(토요일) [마지막]

● W : 가장 가까운 평일 (예) 15W는 15일에서 가장 가까운 평일 (월 ~ 금)을 찾음 [가까운 평일]

● # : 몇째 주의 무슨 요일을 표현 (예) 3#2 : 2번째 주 수요일


글이 길어져서 파일의 목록 처리에 대한 내용은 다음 글로 작성합니다.

 

도움이 되셨다면 광고 한 번 클릭 부탁드립니다. 한 번의 클릭이 제게 큰 힘이 된답니다!^^

 

728x90
반응형