====== File Manage 서비스 ======
===== 개요 =====
비즈니스 로직을 처리하면서 필요한 첨부파일등의 처리를 위한 공통 기능을 제공하여, **파일 목록 조회**, **파일 다운로드** 기능을
공통적으로 사용할 수 있으며 **파일 등록** 부분은 클라이언트 JavaScript 및 그 활용예시를 제공한다.
본 기능은 전자정부 표준프레임워크 실행환경의 **File Upload/Download** 기능을 활용하여 구성되어있다.
===== 설명 =====
파일 업로드를 위한 공통기능은 크게 **MultipartRequest**를 통해서 서버로 전송된 파일을 파싱하여 디스크에 생성하고 해당 정보를 저장하는
**EgovFileMngUtil** 클래스와 파일정보를 관리하기 위한 **EgovFileMngService** 서비스로 구성되어있다.(관련소스 부분 참조)
JSP에서 파일 업로드를 처리하는 부분은 Dynamic HTML 기반으로 되어있으며, 해당 기능처리를 위한 Script는 **EgovMultiFile.js**에
구성되어있다. 이를 각 업로드가 필요한 기능화면에 **[[#사용방법]]**에 의거하여 적용하여 기능 구성을 한다.
== 관련 클래스 다이어그램 ==
{{:egovframework:cdd_공통.gif?900|클래스다이어그램}}
== 관련소스 ==
^유형^대상소스명^비고^
|Controller|egovframework.com.cmm.web.EgovFileMngController.java|파일업로드, 조회를 위한 컨트롤러 클래스|
|Controller|egovframework.com.cmm.web.EgovFileDownloadController.java|파일다운로드를 위한 컨트롤러 클래스|
|Service|egovframework.com.cmm.service.EgovFileMngService.java|파일관리를 위한 서비스 인터페이스|
|ServiceImpl|egovframework.com.cmm.service.impl.EgovFileMngServiceImpl.java|파일관리를 위한 서비스 구현 클래스|
|VO|egovframework.com.cmm.service.FileVO.java|파일관리를 위한 VO 클래스|
|DAO|egovframework.com.cmm.service.imp.FileManageDAO.java|파일정보 관리를 위한 데이터처리 클래스|
|Component|egovframework.com.cmm.service.EgovFileMngUtil.java|파일생성 및 파일정보의 DB저장을 위한 Util 클래스|
|JSP|/WEB-INF/jsp/egovframework/cmm/fms/EgovFileList.jsp|파일목록 조회 및 다운로드 처리를 위한 목록조회 페이지|
|js|/js/egovframework/cmm/fms/EgovMultiFile.js|파일업로드 처리를 위한 Javascript 파일|
== 관련테이블 ==
^테이블명^테이블명(영문)^비고^
|파일정보|COMTNFILE|파일 헤더정보를 관리|
|파일상세정보|COMTNFILEDETAIL|파일 상세정보를 관리|
===== 환경설정 =====
파일 업로드 기능을 활용하기 위하여 필요한 항목 및 그 환경 설정은 다음과 같다.
== context-common.xml ==
본 공통기능에서는 다중파일 업로드 처리를 하기 때문에 그를 위해서 egovframework.com.cmm.web.EgovMultipartResolver 클래스를
MultiCommonsMultipartResolver로서 등록해야 하며 필요시 maxUploadSize, maxInMemorySize의 값을 변경해서 업로드 가능한
최대 파일 크기를 지정한다.
※ spring.RegularCommonsMultipartResolver는 Default 설정으로 추가해둔다.
== context-properties.xml ==
Globals.fileStorePath의 값은 실제 파일이 저장될 수 있는 물리적인 디렉토리 위치를 지정하며 지정시 주소의 가장 뒷 부분에 해당 운영체제에 맞는 File.seperator를 명시하도록 한다.
== context-idgen.xml ==
* ID Generation Service를 활용하기 위해서 Sequence 저장테이블인 COMTECOPSEQ에 FILE_ID 항목을 추가해야 한다.
CREATE TABLE COMTECOPSEQ ( table_name varchar(16) NOT NULL,
next_id DECIMAL(30) NOT NULL,
PRIMARY KEY (table_name));
INSERT INTO COMTECOPSEQ VALUES('FILE_ID','0');
===== 사용방법 =====
상기 설정이 모두 완료된 경우 파일 관리를 사용할 비즈니스 로직에 맞춰서 다음의 4가지 경우에 따른 추가적인 코딩작업을 수행한다.
파일 조회 및 파일 삭제처리를 위한 EgovFileList.jsp에서 사용하는 Javascript의 경우 **Form 명을 frm으로 사용**하고 있음.
별도의 작업을 줄이기 위해서 해당 Form 명을 준수하는 것을 권장함
== File Upload(최초등록) ===
== JSP/Script (File Upload) ==
----
파일을 업로드 하기 위하여 해당 화면에서 사용하는 폼은 다음의 형태를 준수해야 한다.
파일을 등록하기 위하여 먼저 EgovMultiFile.js를 사용할 수 있도록 해당 페이지에 등록한다.
스크립트에서 사용할 파일객체 및 그 파일객체를 쌓아둘 위치를 지정할 수 있도록 다음의 HTML 코드 및 스크립트를 삽입한다.
HTML 코드가 끝나는 위치에 스크립트를 추가해야 하며, 아래의 코드예시에서 document.frm.posblAtchFileNumber.value 값은 업로드가 가능한 최대 파일의 숫자를 form에 담아두기 위한 용도이므로 실제 사용하지 않는 필드라고 해도 추가를 해둬야 한다.
해당 값이 없을 경우에 기본값은 3개이나 필요시 변경이 가능하다.
스크립트와 HTML코드를 모두 작성하고 업무화면을 호출하는 경우 아래와 같은 화면을 확인할 수 있다.
최대 파일수치까지 등록되면 파일찾기 버튼은 비활성화되며 Delete버튼을 누르는 경우 파일 객체를 삭제한다.
{{:egovframework:fileupload2.jpg|}}
== Controller (File Upload) ==
----
업무 비즈니스 처리를 위한 Controller에서는 메서드에서 MultipartHttpServletRequest를 받을 수 있도록
입력항목으로 추가하고 해당 파일요청을 처리하기 위한
import egovframework.com.cmm.service.EgovFileMngService;
import egovframework.com.cmm.service.EgovFileMngUtil;
@Resource(name="EgovFileMngService")
private EgovFileMngService fileMngService;
@Resource(name="EgovFileMngUtil")
private EgovFileMngUtil fileUtil;
public String insertBoardArticle(
final MultipartHttpServletRequest multiRequest,
@ModelAttribute("searchVO") BoardVO boardVO,
@ModelAttribute("board") Board board,
SessionVO sessionVO,
ModelMap model,
SessionStatus status) throws Exception{
List _result = null;
String _atchFileId = "";
final Map files = multiRequest.getFileMap();
if(!files.isEmpty()){
_result = fileUtil.parseFileInf(files, "BBS_", 0, "", "");
_atchFileId = fileMngService.insertFileInfs(_result); //파일이 생성되고나면 생성된 첨부파일 ID를 리턴한다.
}
.....
}
* **EgovFileMngUtil** 클래스의 parseFileInf 메서드는 5개의 인자를 지니고 있으며 각 인자는 파일 객체, 구분 값, 파일 순번, 파일ID, 저장경로이며 파일 ID가 빈 문자열 또는 null로 들어올 경우 **IDGenerationService**를 통해서 신규로 생성하며
* 저장경로가 빈 문자열 또는 null로 들어오는 경우 **context-properties.xm**에 지정된 파일저장 경로를 사용하게 되며 파일 순번의 경우 최초 등록시에는 0을 세팅한다.
* 구분 값은 실제 파일이 물리적인 저장위치에 변경된 이름으로 저장될 때 해당 파일이름 생성시에 사용되며 현재 파일 생성규칙은 "구분 값"+"yyyyMMddhhmmssSSS형태의 TimeStamp값"+"파일 키"의 형태로 생성된다.
== File Select ===
----
- 해당 업무로직에서 첨부파일이 있는 것이 확인 될 경우 아래의 코드예시처럼 해당 게시물에 등록된 첨부파일 ID를 Parameter로 전송한다.
- 파일목록의 조회가 완료되는 경우 **새 텍스트 문서.txt [405 byte] ** 처럼 저장된 파일명과 파일의 크기가 표시된다.
- File Select의 경우 파일을 삭제하는 기능버튼은 활성화되지 않으며 파일의 다운로드를 위한 링크만이 존재한다.
== File Delete ===
----
- 해당 업무로직에서 첨부파일을 삭제할 필요가 있는 경우 (게시물의 수정등) 사용하며 File Select의 경우와 마찬가지로 등록된 첨부파일 ID를 Parameter로 전송한다.
- File Select의 경우와는 반대로 파일 다운로드 링크는 존재하지 않으며 파일 삭제를 위한 삭제버튼이 활성화된다.
* 다만 파일 삭제시 전체 화면에 대해서 Submit()이 발생하기 때문에 삭제 후 다시 돌아올 페이지를 지정해줘야 한다.
* 이를 위해서 삭제대상 업무기능페이지에 다음의 HTML Object를 추가하여 다시 돌아올 페이지를 아래의 예시처럼 지정한다.
== File Upload(수정등록) ===
----
파일을 업로드 하기 위하여 해당 화면에서 사용하는 폼은 다음의 형태를 준수해야 한다.
== JSP/Script (File Upload - 수정등록) ==
----
비즈니스 로직 상에서 수정 시점에 파일을 첨부하거나 삭제하는 경우이며, 현재 해당 모듈에서는 파일의 삭제와 저장을 분리하여 별도의 **Transaction**으로 처리하고 있다.
이 경우에도 최초등록때와 마찬가지로 먼저 EgovMultiFile.js를 사용할 수 있도록 해당 페이지에 등록한다.
앞서 이야기한바와 같이 수정 시점에서는 기존에 등록된 파일을 삭제하거나 신규로 등록하는 형태로 진행되므로 신규로 파일을 입력할 수 있는 부분과 파일을 삭제하는 부분을 모두 한 업무화면에 표현해야 한다.
파일 목록을 조회하고 삭제하는 부분은 기존의 파일 삭제때와 마찬가지로 처리하며
파일을 쌓는 부분은 아래와 같은 HTML 코드를 준비한다.
DIV를 file_upload_posbl, file_upload_imposbl로 나눠둔 것은 메시지 처리등을 위한 부분이며 개선의 여지가 있다.
HTML 코드가 끝나는 위치에 스크립트를 추가해야 하며, 아래의 코드예시에서 document.frm.posblAtchFileNumber.value 값은 업로드가 가능한 최대 파일의 숫자를 form에 담아두기 위한 용도이므로 실제 사용하지 않는 필드라고 해도 추가를 해둬야 한다.
파일 등록때와 마찬가지로 파일 업로드 기능에서 사용하는 Form명은 frm이다.
스크립트와 HTML코드를 모두 작성하고 업무화면을 호출하는 경우 아래와 같은 화면을 확인할 수 있다.
최대 파일수치까지 등록되면 파일찾기 버튼은 비활성화되며 Delete버튼을 누르는 경우 파일 객체를 삭제한다.
{{:egovframework:fileupload2.jpg|}}
== Controller (File Upload - 수정등록) ==
----
import egovframework.com.cmm.service.EgovFileMngService;
import egovframework.com.cmm.service.EgovFileMngUtil;
@Resource(name="EgovFileMngService")
private EgovFileMngService fileMngService;
@Resource(name="EgovFileMngUtil")
private EgovFileMngUtil fileUtil;
public String updateBoardArticle(
final MultipartHttpServletRequest multiRequest,
@ModelAttribute("searchVO") BoardVO boardVO,
@ModelAttribute("board") Board board,
SessionVO sessionVO,
ModelMap model,
SessionStatus status) throws Exception{
String _atchFileId = boardVO.getAtchFileId();/ 해당 업무기능에 따라서 수정되는 기능의 파일 ID를 불러온다.
final Map files = multiRequest.getFileMap();
if(!files.isEmpty()){
if("".equals(_atchFileId)){
List _result = fileUtil.parseFileInf(files, "BBS_", 0, _atchFileId, "");
_atchFileId = fileMngService.insertFileInfs(_result); // 기존에 첨부파일 ID가 없다.
board.setAtchFileId(_atchFileId); // 관련 비즈니스 규칙에 따라서 생성된 첨부파일 ID 정보를 세팅한다.
}else{
FileVO fvo = new FileVO();
fvo.setAtchFileId(_atchFileId); // 최종 파일 순번을 획득하기 위하여 VO에 현재 첨부파일 ID를 세팅한다.
int _cnt = fileMngService.getMaxFileSN(fvo); // 해당 첨부파일 ID에 속하는 최종 파일 순번을 획득한다.
List _result = fileUtil.parseFileInf(files, "BBS_", _cnt, _atchFileId, "");
fileMngService.updateFileInfs(_result);
}
}
......
* 기본적인 흐름은 최초 생성의 경우와 동일하다. 다만 기존에 첨부파일 ID가 존재하는 경우 해당 첨부파일 ID에 속하는 최종 FILE_SN(파일순번)을 획득해서
* 해당 파일 순번과 첨부파일 ID를 parseFileInf 메서드에 인자로 제공해야 한다. 이후의 파일 생성로직은 최초 생성때와 동일하다.
* 기존에 이미 파일이 존재하는 경우인 updateFileInfs 메서드는 리턴값이 없음을 확인하도록 한다.
===== 참고자료 =====
* 실행환경 참조 : [[eGovframework:RTE:FDL:File Upload/Download]]