[개인 프로젝트] SJBoard (댓글 및 파일 업로드 게시판) 5일차 개발 일지
2022.03.11.금요일 5일차
드디어 지난 5일 동안 스프링의 AOP, 트랜잭션, 파일 업로드 기능을 학습하여 SJBoard 에 파일 업로드 기능을 구현해보았다.
1. 파일 업로드 구현 설계
1) 첨부파일의 종류를 이미지 파일과 일반 파일로 나누고, 각 페이지에서의 작업이 어떻게 처리되면 좋을지 구상
이미지 파일 | 일반 파일 | |
register.jsp (게시물 등록) |
- 파일 첨부란에 업로드 하고자 하는 이미지 파일의 섬네일 이미지가 나타나도록 한다. - 파일 첨부란에서 파일 이름 옆 x 버튼 클릭 시 해당 파일이 파일 첨부란에서 사라지도록 한다. |
- 파일 첨부란에 일반 문서 이미지가 나타나도록 한다. (구글에서 무료 이미지를 찾아 attach.png로 활용) - 파일 첨부란에서 파일 이름 옆 x 버튼 클릭 시 해당 파일이 파일 첨부란에서 사라지도록 한다. |
get.jsp (게시물 조회) |
- 파일 첨부란에 해당 게시물에 등록된 이미지 파일의 섬네일 이미지가 나타나도록 한다. (register.jsp와 동일) - 섬네일 이미지 클릭 시 원본 이미지가 화면에 나타나도록 한다. |
- 파일 첨부란에 해당 게시물에 등록된 파일의 일반 문서 이미지가 나타나도록 한다. (register.jsp와 동일) - 원본 이미지 클릭 시 일반 파일을 다운로드할 수 있게 한다. |
modify.jsp (게시물 수정) |
- 게시물 수정 시) * 이미 등록된 첨부 파일의 삭제 * 첨부 파일 추가 등록 - 게시물 삭제 시) * 게시물과 함께 등록되어있던 첨부파일도 함께 삭제되어야 한다. |
2) 파일 업로드 구현 방법: Ajax
- Ajax로 구현하는 이유:
* Drag and Drop 기능을 사용하여 사용자가 쉽게 파일을 첨부할 수 있게 하고자 함
* 댓글 기능과 함께 웹 페이지 동작의 일관성을 유지하기 위함
3) 파일 업로드 시 고려해야하는 사항:
- 동일한 이름으로 파일이 업로드 되었을 때 기존 파일이 사라지는 문제
-> 게시판 첨부 파일을 모아 놓는 업로드 폴더 내에 '연/월/일' 폴더를 생성하여 업로드 날짜별로 파일을 구분할 수 있도록 설계
-> java.util.UUID 클래스를 사용하여 파일 이름 앞에 UUID 값을 추가하고 '_'로 구분될 수 있도록 설계
예) 이미지 파일(img.jpg)의 파일명: uuid값_img.jpg
일반 파일(docu.doc)의 파일명: uuid값_docu.doc
- 이미지 파일의 경우에는 원본 파일의 용량이 큰 경우 섬네일 이미지를 생성해야 하는 문제
-> Thumbnailator 라이브러리를 이용하여 섬네일 이미지 생성
-> 섬네일 이미지의 경우 원본 이미지와의 파일명 구분을 위해 's_UUID_파일명'으로 저장되도록 설계
- 첨부파일 공격에 대비하기 위한 업로드 파일의 확장자 제한
-> 파일 당 최대 용량은 5MB로 지정
-> 확장자가 exe, sh, zip, alz 인 파일의 업로드 금지 설정
4) 첨부 파일들의 정보를 관리할 데이터베이스 설계
- 오라클 데이터베이스에 첨부파일 정보를 가진 테이블 TBL_ATTACH 설계 후 기존 게시판 테이블 TBL_BOARD와 게시물 번호(bno)로 외래키 연결 필요
- TBL_ATTACH 에는 UUID (파일 중복 구분을 위한 uuid값), UPLOADPATH (파일이 최종 업로드 되는 년/월/일 폴더 경로), FILENAME(파일 이름), FILETYPE(이미지 여부 확인), BNO(게시물 번호) 열을 생성
5) 잘못 업로드된 파일 삭제 설계
- 비정상적으로 브라우저를 종료하거나 페이지를 빠져나간 경우 게시물에 첨부파일이 존재하지 않으나 서버에는 첨부파일이 그대로 남아있는 경우 해당 파일들은 서버 내 파일 폴더에서 반드시 삭제되어야 함
- 데이터베이스 TBL_ATTACH 테이블의 기록을 기준으로 매일 새벽 2시 오늘 날짜가 아닌, 전날 업로드된 파일들을 대상으로 스케줄링하여 서버 내 불필요한 파일들을 삭제하도록 Quartz 라이브러리를 이용
2. 제작 과정
1) 오라클 데이터베이스 내 첨부파일 정보를 가진 테이블 TBL_ATTACH 생성
- 파일 업로드 구현 설계에서 했듯이 TBL_ATTACH의 열을 생성하고 TBL_BOARD와 BNO를 기준으로 외래키 연결
2) 첨부파일 영속 영역 구현
- 데이터베이스에 생성한 TBL_ATTACH 테이블 내 열을 기준으로 게시판 파일 첨부 VO 클래스인 BoardAttachVO 클래스를 작성
- 첨부파일 정보를 데이터베이스를 이용하여 보관하므로 이를 처리하는 BoardAttachMapper 인터페이스와 SQL문을 담당하는 BoardAttachMapper.xml 작성
- 첨부파일 관리에 필요한 값들을 저장하는 AttachFileDTO 생성
3) 첨부파일 비즈니스 계층 구현
- 기존 BoardService 인터페이스에 첨부파일 기능 추가로 해당 게시물의 첨부파일 목록을 가져오는 메서드 getAttachList()를 추가
- 기존 BoardServiceImpl 클래스에 인터페이스에서 새로 추가한 getAttaachList()를 오버라이드 처리
- 게시물 생성 처리 메서드 register(), 수정 처리 메서드 modify(), 삭제 처리 메서드 remove()에 트랜잭션 처리
4) 첨부파일 컨트롤러 구현
- 파일 첨부 작업을 담당하는 UploadController 클래스 작성
- 첨부 파일 작업은 게시물과 밀접하게 관련되어 있으므로 기존 BoardController 클래스에도 파일 첨부와 관련된 작업을 추가
4-1) UploadController
- Ajax를 이용하여 파일 첨부 작업을 구현하므로 @RestController 어노테이션 이용
ask | URL | Method | Parameter | From (별도의 입력화면 필요여부) |
URL 이동 여부 |
파일 업로드 처리 | /uploadAjaxAction | POST | uploadfile | Ajax로 처리하므로 별도의 입력화면이나 URL 이동은 필요없음 |
|
이미지 파일인 경우 섬네일 표시 |
/display | GET | filename | ||
일반 파일인 경우 첨부파일 다운로드 |
/download | GET | userAgent (IE 호환을 위한 브라우저엔진 확인용) filename |
||
게시물 작성 시 첨부파일 삭제 |
/deletefile | POST | filename, type |
4-2) BoardController
- 기존 메서드에 파일 첨부와 관련된 작업을 추가하고 파일 첨부 작업에 필요한 새로운 메서드 추가
(Ajax를 이용하는 메서드에만 @ResponseBody 어노테이션을 추가하여 기존 @Controller 어노테이션 유지 )
ask | URL | Method | Parameter | From (별도의 입력화면 필요여부) |
URL 이동 여부 |
게시물 조회 시 해당 게시물의 첨부 목록도 가져옴 | /getAttachList | GET | bno | Ajax로 처리하므로 별도의 입력화면이나 URL 이동은 필요없음 |
5) 첨부파일 등록/조회/수정/삭제를 위한 view 페이지 수정 및 javascript 작성
view 페이지명 | 작업 내용 |
register.jsp (게시물 등록) |
- 게시물 작성 화면의 '내용'란 하단에 첨부파일이 들어갈 <div> 추가 - 첨부파일 관련 작업은 자바스크립트 제이쿼리로 구현 1) 파일 확장자와 파일 용량 확인 함수 * 정규식으로 파일 확장자 exe, sh, zip, alz 업로드 제한 * 파일 당 최대 용량 5MB 지정 2) 사용자가 첨부파일을 선택할 시 파일 업로드 작업 진행 함수 3) 업로드 결과 화면 출력 함수 * 이미지 파일 / 일반 파일 구분 4) 파일 업로드 작업 ajax 처리 5) 게시물 등록 시 첨부파일 목록 전달 함수 6) 원하지 않는 첨부파일 삭제 처리 함수 |
get.jsp (게시물 조회) |
- 게시물 작성 화면의 '내용'란 하단에 첨부파일이 들어갈 <div> 추가 - 첨부파일 관련 작업은 자바스크립트 제이쿼리로 구현 1) 첨부파일 클릭 시 동작 함수 * 이미지 파일: 원본 이미지를 보여줌 * 일반 파일: 파일 다운로드 (다운로드 여부를 묻고 진행) |
modify.jsp (게시물 수정) |
- 게시물 작성 화면의 '내용'란 하단에 첨부파일이 들어갈 <div> 추가 - 첨부파일 관련 작업은 자바스크립트 제이쿼리로 구현 (register.jsp에서의 작업과 거의 유사) |
6) 서버 내 잘못 업로드된 파일 삭제를 위한 task 클래스 작성
- Quartz 라이브러리를 이용하여 서버 내 잘못 업로드된 파일을 삭제하기 위해 task 패키지 및 FileCheckTask 클래스 생성
- 데이터베이스 TBL_ATTACH 테이블의 기록을 기준으로 매일 새벽 2시 오늘 날짜가 아닌, 전날 업로드된 파일들을 대상으로 스케줄링하여 서버 내 불필요한 파일들을 삭제하도록 FileCheckTask 클래스 작성
- BoardAttachMapper 와 BoardAttachMapper.xml에 전날의 모든 첨부파일 목록을 가져오는 메서드와 SQL문을 작성
3. 발생 에러 및 해결 방법
4. 오늘 프로젝트 진행하면서 추가로 배운 내용