====== 엑셀 처리 가이드 ======
===== 엑셀 연동 방식 개요 =====
엑셀 연동 방식에 대한 개요 및 구조는 아래와 같습니다. 연동 방식에 대한 변경은 실행 파라미터에 의해서 결정됩니다.
==== 엑셀 연동 방식 개요 ====
|< 100% 10% 30% 30% 30% >|
^ 구분 ^ WAS 서버 연동 방식 ^ 로컬 엑셀 오토메이션 방식 ^ 로컬 스크립트 방식 ^
| 기반 기술 |
* xFrame5 EXCEL 처리 스크립트 모듈
* Apache POI 라이브러리
* xFrame5 XEXCEL 자바 라이브러리
|
* xFrame5 EXCEL 처리 스크립트 모듈
* 엑셀 오토메이션 기술
* xFrame5 전용 브라우저
|
* xFrame5 EXCEL 처리 스크립트 모듈
* 엑셀 처리용 오픈소스 자바스크립트 라이브러리
|
| xFrame5\\ 실행 환경 |
* 범용 브라우저, xFrame5 전용 브라우저
|
* xFrame5 전용 브라우저 (범용 브라우저 불가)
|
* 범용 브라우저, xFrame5 전용 브라우저
|
| 실행 환경 |
* Java 기반 WAS 서버
* JDK 1.6 이상
* 고객사에 적용된 DRM 솔루션 회사에서 제공하는 DRM 해제/설정 자바 라이브러리
|
* 사용자 PC에 엑셀 프로그램이 설치되어 있어야 함
|
* 실행 환경제약 사항 없음
* 기본 방식으로는 DRM 해제/설정 불가
|
| 처리 속도 |
* 보통
|
* 조금 우수\\ (엑셀 오토메이션 작업으로 인한 처리 시간 증대)
|
* 우수
|
| 서버 부하 |
* 대량 데이터 및 사용자가 많은 경우, 서버에 부하(메모리, CPU) 발생
|
* 서버 부하 없음
|
* 서버 부하 없음
|
| 파일 선택 및\\ 저장 경로 |
* 사용자 선택 (직접 경로 지정 불가)
|
* 사용자 선택 및 직접 경로 지정 가능
|
* 사용자 선택 (직접 경로 지정 불가)
|
===== DRM 처리 =====
==== DRM 처리 방식 상세 내용 ====
=== 엑셀 연동 방식에 대한 개요 및 구조는 아래와 같습니다. 연동 방식에 대한 변경은 실행 파라미터에 의해서 결정됩니다. ===
|< 100% 10% 30% 30% 30% >|
^ 구분 ^ WAS 서버 연동 방식 ^ 로컬 엑셀 오토메이션 방식 ^ 로컬 스크립트 방식 ^
| 엑셀 파일\\ 업로드\\ DRM 해제 |
* DRM 솔루션 회사에서 제공하는 DRM 해제 자바 라이브러리를 연동하여 xFrame5 XEXCEL 자바 라이브러리에서 DRM 해제 수행
|
* 엑셀 프로그램에서 DRM 해제
|
기본적으로 DRM 해제 불가로 인해 엑셀 업로드 동작 오류 발생\\
[DRM 해제 방안]\\
- 방안1 (권고 방안)\\
xFrame5 전용 브라우저인 경우, DRM 솔루션에서 xFrame5 전용 브라우저를 엑셀 프로그램처럼 DRM 자동 해제 방식 적용 가능\\
- 방안 2\\
xFrame5 전용 브라우저인 경우, 엑셀 업로드시 DRM 해제를 위한 DRM 솔루션 연계 커스트마이징 개발 필요\\
- 방안 3\\
GRID_EXCELUPLOAD_METHOD2_DRMURL 실행 파라미터를 지정하여,
엑셀 업로드시 DRM 솔루션 연계한 DRM 해제 처리 모듈(하단 XDrmUtil.java 소스 참조) 커스트마이징 개발
|
| 엑셀 파일\\ 다운로드\\ DRM 적용 |
* DRM 솔루션 회사에서 제공하는 DRM 적용 자바 라이브러리를 연동하여 xFrame5 XEXCEL 자바 라이브러리에서 수행
|
* 엑셀 저장시 DRM 적용이 필요한 경우, "로컬 스크립트 방식"으로 엑셀 파일 저장 후
* 엑셀 프로그램 기동 및 저장 작업을 수행하여 DRM 적용
|
기본적으로 엑셀 파일 저장시 DRM 적용 안됨\\
[DRM 적용 방안]\\
- 방안 1 (권고 방안)\\
DRM 솔루션에서 자동으로 DRM 적용 처리\\
- 방안 2\\
xFrame5 전용 브라우저인 경우, 엑셀 저장시 DRM 적용을 위한 DRM 솔루션 연계 커스트마이징 개발 필요\\
- 방안 3\\
GRID_EXCELDOWNLOAD_METHOD2_DRMURL 실행 파라미터를 지정하여,
엑셀 저장시 DRM 솔루션 연계한 DRM 적용 처리 모듈(하단 XDrmUtil.java 소스 참조) 커스트마이징 개발
|
| 고객사\\ 보안 솔루션\\ 정책 확인 |
* 범용 브라우저/xFrame5 전용 브라우저에서 WAS 서버로 파일 업로드 보안 허용
* 범용/xFrame5 전용 브라우저에서 파일 다운로드 보안 허용
| xFrame5 전용 브라우저에서 파일 다운로드 보안 허용 | 범용 브라우저/xFrame5 전용 브라우저에서 파일 다운로드 보안 허용 |
===== 엑셀 업로드 상세 방식 =====
==== 엑셀 업로드 상세 방식 ====
=== 엑셀 업로드 방식에 대한 자세한 내용은 아래와 같습니다. ===
|< 100% 10% 30% 30% 30% >|
^ 구분 ^ WAS 서버 연동 방식 ^ 로컬 엑셀 오토메이션 방식 ^ 로컬 스크립트 방식 ^
| 엑셀 업로드 절차 |
* 사용자가 엑셀 파일 선택 (API에서 직접 경로 지정 불가)
* 사용자가 선택한 파일을 WAS 서버에 HTTP 멀티 파트 형태로 업로드
* WAS 서버의 xFrame5 XEXCEL 자바 라이브러리에서 업로드된 엑셀 파일 파싱 및 데이터 추출하여 리턴
* GRID에서 수신된 데이터 처리 및 표시
|
* 사용자가 엑셀 파일 선택 (API에서 직접 경로 지정 가능)
* xFrame5 전용 브라우저에서 엑셀 프로그램을 기동하여 엑셀 프로그램에서 엑셀 파일 로드 후, 엑셀 프로그램과의 인터페이스를 통해 데이터 추출 및 리턴
* GRID에서 추출된 데이터 처리 및 표시
|
* 사용자가 엑셀 파일 선택 (API에서 직접 경로 지정 불가)
* xFrame5 XEXCEL 스크립트 라이브러리에서 사용자가 선택한 엑셀 파일 파싱 데이터 추출 및 리턴
* GRID에서 추출된 데이터 처리 및 표시
|
| 실행 파라미터 | GRID_EXCELUPLOAD_METHODTYPE 파라미터
* 엑셀 다운로드 방식 지정
* 파라미터 값 : 0 (기본값)
| GRID_EXCELUPLOAD_METHODTYPE 파라미터
* 엑셀 업로드 방식 지정
* 파라미터 값 : 1
| GRID_EXCELUPLOAD_METHODTYPE 파라미터
* 엑셀 업로드 방식 지정
* 파라미터 값 : 2
|
===== 엑셀 다운로드 상세 방식 =====
==== 엑셀 다운로드 상세 방식 ====
=== 엑셀 다운로드 방식에 대한 자세한 내용은 아래와 같습니다. ===
|< 100% 10% 30% 30% 30% >|
^ 구분 ^ WAS 서버 연동 방식 ^ 로컬 엑셀 오토메이션 방식 ^ 로컬 스크립트 방식 ^
| 엑셀 다운로드\\ 절차 |
* 그리드의 내용을 WAS 서버에 HTTP POST 형태로 송신
* WAS 서버의 xFrame5 XEXCEL 자바 라이브러리에서 수신된 데이터를 이용하여 엑셀 파일 생성 및 엑셀 파일 리턴
* 수신된 엑셀 파일 저장
* 경로 지정 파일 저장 불가(저장시 사용자가 폴더 지정 경로 지정)
|
* 그리드의 내용을 xFrame5 XEXCEL 스크립트 라이브러리에서 엑셀 데이터 생성하여 xFrame5 전용 브라우저에게 전달
* xFrame5 전용 브라우저에서 엑셀 프로그램 기동 및 저장
* 경로 지정 파일 저장 가능
|
* XLSX 파일 형식만 지원
* 그리드의 내용을 xFrame5 XEXCEL 스크립트 라이브러리에서 엑셀 파일 생성 및 엑셀 파일 저장
* 경로 지정 파일 저장 불가(파일 저장시 사용자가 폴더 지정 경로 지정)
|
| 실행 파라미터 | GRID_EXCELDOWNLOAD_METHODTYPE 파라미터
* 엑셀 다운로드 방식 지정
* 파라미터 값 : 0 (기본값)
| GRID_EXCELDOWNLOAD_METHODTYPE 파라미터
* 엑셀 다운로드 방식 지정
* 파라미터 값 : 1
| GRID_EXCELDOWNLOAD_METHODTYPE 파라미터
* 엑셀 다운로드 방식 지정
* 파라미터 값 : 2
|
| 세부 옵션\\ 실행 파라미터 | XEXCEL_DOWNLOAD_URL 파라미터
* XExcelDownload 서블릿 URL 지정
* 예시 - ”./xframe5/XExcelDownload”
| | |
| 엑셀 파일\\ 비밀번호 설정 |
* XExcelUpload 서블릿에서 엑셀 파일 비밀번호 지정 처리
| |
* 로컬 스크립트에서 엑셀 파일 비밀번호 지정 처리
* 처리 시간이 조금 더 걸림
|
===== 제약 사항 =====
==== 상세 내용 ====
=== 엑셀 연동 관련 제약 사항에 대한 자세한 내용은 아래와 같습니다.===
|< 100% 10% 30% 30% 30% >|
^ 구분 ^ WAS 서버 연동 방식 ^ 로컬 엑셀 오토메이션 방식 ^ 로컬 스크립트 방식 ^
| 엑셀 업로드\\ 파일크기 |
* 그리드 excel_upload_maxsize 속성
* 그리드 get/setuploadexcelmaxsize API 제공
|
* N/A
|
* N/A
|
| 실행 파라미터 | GRID_EXCELUPLOAD_MAXSIZE 파라미터
* 업로드할 파일 최대 크기 지정
* 기본값: 0 (제한없음)
* 단위: 바이트
* 그리드 excel_upload_maxsize 속성이 0인 경우 사용됨
| | |
===== XDrmUtil.java 소스 =====
XDrmUtil.java 파일은 GRID_EXCELUPLOAD_METHODTYPE/GRID_EXCELDOWNLOAD_METHODTYPE 실행 파라미터가 2인 경우,
각각 엑셀 파일에 대한 DRM 해제 및 적용 처리를 위한 샘플 자바 서블릿 소스이다.
프로젝트 진행시에는 고객사의 DRM 솔루션과의 연계 로직을 추가하여 사용해야 한다.
소스 파일
* XDrmUtil.java
==== 소스 ====
package xframe5.template.html5.component.grid;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.PushbackInputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletContext;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.output.DeferredFileOutputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class XDrmUtil extends HttpServlet
{
private static final long serialVersionUID = 3347918932345852889L;
/****************************************************************
* 프로젝트 적용시 변경 대상 시작
****************************************************************/
protected final Log logger = LogFactory.getLog(getClass());
// 업로드된 파일 처리용 임시 파일을 저장할 디렉토리 절대 경로 (프로젝트 적용시 변경필요)
String tempDirAbsolutePath = "C:\\xFrame5\\temp";
// 업로드된 파일을 임시로 저장할 디렉토리 절대 경로 (프로젝트 적용시 변경필요)
String saveBaseDirAbsolutePath = "C:\\xFrame5\\temp";
int maxMemoryFileSize = 10; // maximum memory file size
int maxFileSize = 1000 * 1024 * 1024; // maximum file size (1000MB)
/**
* 메시지 로깅
* @return
*/
public void logMsg(String msg)
{
// logger.info(msg);
System.out.println(msg);
}
/**
* 파일 업로드 처리시 사요한 임시 저장 디렉토리 및 파일 저장 디렉토리 설정
* (getContextRootPath 함수 활용)
* @return
*/
public void setTempAndSaveDirPath(HttpServletRequest request)
{
String contextRootAbsolutePath;
// Web Application이 실행되는 루트 절대 경로를 구함
contextRootAbsolutePath = getContextRootPath(request);
if (contextRootAbsolutePath.endsWith(File.separator) == false) {
contextRootAbsolutePath += File.separator;
}
logMsg("contextRootPath = [" + contextRootAbsolutePath + "]");
// 업로드된 파일 처리용 임시 파일을 저장할 디렉토리 절대 경로 (프로젝트 적용시 변경필요)
// tempDirAbsolutePath = "C:\\xFrame5\\temp";
tempDirAbsolutePath = contextRootAbsolutePath + "temp";
logMsg("tempDirAbsolutePath = [" + tempDirAbsolutePath + "]");
// 업로드된 파일을 임시로 저장할 디렉토리 절대 경로 (프로젝트 적용시 변경필요)
// saveBaseDirAbsolutePath = "C:\\xFrame5\\temp";
saveBaseDirAbsolutePath = contextRootAbsolutePath + "temp";
logMsg("saveBaseDirAbsolutePath = [" + saveBaseDirAbsolutePath + "]");
}
/**
* Request에서 전달된 파라미터 KEY/VALUE 맵과 저장된 파일 경로를 이용하여
* DRM 적용/해제 및 DRM 적용/해제된 파일 절대 경로 반환
* @param paramMap Request에서 전달된 파라미터 KEY/VALUE 맵
* @param saveFileAbsolutePath 저장된 파일 경로
* @return DRM 적용/해제된 파일 절대 경로 반환
*/
public String drmProcess(HashMap paramMap, String saveFileAbsolutePath)
{
String returnFileAbsolutePath;
// TODO: DRM 적용 또는 해제 처리 및 처리 결과 파일 경로 반환
returnFileAbsolutePath = saveFileAbsolutePath;
return returnFileAbsolutePath;
}
/****************************************************************
* 프로젝트 적용시 변경 대상 끝
****************************************************************/
String errorMsg = ""; // error message
String fileName = ""; // uplaod file name
String browserType = ""; // browser type
public void doGet(HttpServletRequest request, HttpServletResponse response) {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) {
ServletFileUpload uplaodHandler = null; // file uplaod handler
List> fileItemList = null; // file item list
FileItem fileItem = null; // file item
String saveFileAbsolutePath = "";
byte[] buffer = null;
int numRead = -1;
FileInputStream fis = null;
ServletOutputStream sos = null;
// POST 방식으로 전달되는 파일 이외의 값을 저장하기 위한 HashMap
HashMap paramMap = new HashMap();
// 임시로 파일 이름 및 절대 경로를 지정함
// 실제 환경에서는 request에서 파일 이름, 저장할 파일 이름을 구하고, 파일 이름에 해당하는 절대 경로를 구해야 함.
String returnFileAbsolutePath = "";
logMsg("XDrmUtil Start ----------------------------------------------------");
try {
// Get Response Output Stream
sos = response.getOutputStream();
setTempAndSaveDirPath(request);
// Set Response Common Header
setResponseCommonHeader(request, response);
// Get Upload File Processor Object
uplaodHandler = getFileUploadProcessor();
logMsg("Success to create a file upload handler");
// Parse request Data
fileItemList = uplaodHandler.parseRequest(request);
// Get Parameter Key/Value Map
getParamValueMap(fileItemList, paramMap);
// Process File Data
Iterator> iter = fileItemList.iterator();
while (iter.hasNext()) {
fileItem = (FileItem)iter.next();
// Skip Normal Form Field Item
if (fileItem.isFormField()) { continue; }
// Save Upload File Multipart Data
saveFileAbsolutePath = handleUploadFile(fileItem, paramMap);
if (saveFileAbsolutePath == null) {
logMsg("saveFileAbsolutePath is null, errorMsg = " + errorMsg);
returnErrorMsg(response, sos, errorMsg);
return;
}
break;
}
// DRM 적용/해제 처리 및 처리 결과 파일 경로를 returnFileAbsolutePath 변수에 저장
returnFileAbsolutePath = drmProcess(paramMap, saveFileAbsolutePath);
// Create Byte Array For Read File
buffer = new byte[4096];
// Create File Object For Return File Path
File file = new File(returnFileAbsolutePath);
long fileSize = file.length();
// Set HTTP Response HTTP Header
setResponseHeader(response, fileName, fileSize);
// Read Return File Content & Write File Content to Output Stream
fis = new FileInputStream(new File(returnFileAbsolutePath));
while((numRead = fis.read(buffer, 0, 4096)) != -1){
sos.write(buffer, 0, numRead);
}
sos.flush();
}
catch (Exception e) {
logMsg(e.getMessage());
e.printStackTrace();
// Return Error Message
try { returnErrorMsg(response, sos, e.getMessage()); }
catch (Exception ignore) {}
}
catch (Throwable e) {
logMsg(e.getMessage());
e.printStackTrace();
}
finally {
// Close File Input Stream
if (fis != null) {
try { fis.close(); }
catch (Exception ignore) {}
}
// Close Servlet Output Stream
if (sos != null) {
try { sos.close(); }
catch (Exception ignore) {}
}
logMsg("delete " + saveFileAbsolutePath);
deleteFile(saveFileAbsolutePath);
logMsg("delete " + returnFileAbsolutePath);
deleteFile(returnFileAbsolutePath);
}
}
public void returnErrorMsg(HttpServletResponse response, ServletOutputStream sos, String errorMsg) throws IOException
{
// 에러 발생시 메세지 리턴용
// StartDelimiter + 에러메시지 + EndDelimiter
String WFM_DATASTART_DEL = String.valueOf((char)0x1C) + "xFrame5ErrorS" + String.valueOf((char)0x1C); // data start indicator
String WFM_DATAEND_DEL = String.valueOf((char)0x1F) + "xFrame5ErrorE" + String.valueOf((char)0x1F); // data end indicator
String errMsg = WFM_DATASTART_DEL + errorMsg + WFM_DATAEND_DEL;
byte[] arrReturn = errMsg.getBytes("UTF-8");
response.setContentType("text/html");
response.setHeader("Content-Length", String.valueOf(arrReturn.length));
sos.write(arrReturn);
}
// request 파싱 처리 결과 리스트에서 파일 데이터를 제외한 일반 KEY/VALUE 값을 추출하여 HashMap에 저장
public void getParamValueMap(List> fileItemList, HashMap paramMap) throws UnsupportedEncodingException
{
FileItem fileItem = null; // file item
// request 파싱 처리 결과 리스트에서 파일 데이터를 제외한 일반 KEY/VALUE 값을 추출하여 HashMap에 저장
Iterator> iter1 = fileItemList.iterator();
while (iter1.hasNext()) {
fileItem = (FileItem)iter1.next();
// 일반 Form 필드 값을 추출하여 paramMap HashMap에 저장
if (fileItem.isFormField()) {
String fieldName = fileItem.getFieldName();
String fieldValue = fileItem.getString();
// EXCEL_GLOBAL_INFO값등을 인코딩을 해서 올리므로 디코딩함(EXCEL_GLOBAL_INFO값에 한글이 있는 경우관련)
fieldValue = URLDecoder.decode(fieldValue, "UTF-8");
paramMap.put(fieldName, fieldValue);
logMsg("fieldName = [" + fieldName + "], fieldValue = [" + fieldValue + "]");
}
}
}
public void setResponseCommonHeader(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException
{
String origin = "";
boolean bCorsHeader = true; // cors_header 사용할지 여부
browserType = getBrowserType(request);
logMsg("browserType: " + browserType);
// Set cross domain response header
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Headers", "X-Requested-With");
// a String containing the value of the requested header, or null if the request does not have a header of that name
origin = request.getHeader("Origin");
logMsg("origin = " + origin);
if (origin == null) {
response.setHeader("Access-Control-Allow-Origin", "*");
}
else {
response.setHeader("Access-Control-Allow-Origin", origin);
}
}
public void setResponseHeader(HttpServletResponse response, String saveAsFileName, long fileSize) throws UnsupportedEncodingException
{
response.setHeader("Content-Length", String.valueOf(fileSize));
response.setHeader("Content-Transfer-Encoding", "binary");
response.setHeader("Accept-Ranges", "bytes");
response.setHeader("Set-Cookie", "fileDownload=true; path=/");
/*
// "Content-disposition: attachment"은
// 브라우저 인식 파일확장자를 포함하여 모든 확장자의 파일들에 대해, 다운로드시 무조건 "파일 다운로드" 대화상자가 뜨도록 하는 헤더속성이라 할 수 있다.
if(userAgent.indexOf("Safari") > -1) {
response.setHeader("Content-Disposition", "attachment; filename=" + excelFileName);
} else {
response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + excelFileName);
}
*/
if (browserType.contains("IE")) {
saveAsFileName = URLEncoder.encode(saveAsFileName, "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-Disposition", "attachment;filename=" + saveAsFileName + ";");
}
else if (browserType.contains("FIREFOX")) {
saveAsFileName = new String(saveAsFileName.getBytes("UTF-8"), "ISO-8859-1");
response.setHeader("Content-Disposition", "attachment; filename=\"" + saveAsFileName + "\"");
}
else if (browserType.contains("OPERA")) {
saveAsFileName = new String(saveAsFileName.getBytes("UTF-8"), "ISO-8859-1");
response.setHeader("Content-Disposition", "attachment; filename=\"" + saveAsFileName + "\"");
}
else if (browserType.contains("CHROME")) {
saveAsFileName = new String(saveAsFileName.getBytes("UTF-8"), "ISO-8859-1");
response.setHeader("Content-Disposition", "attachment; filename=\"" + saveAsFileName + "\"");
}
else if (browserType.contains("SAFARI")) {
response.setHeader("Content-Disposition", "attachment; filename=" + saveAsFileName);
}
}
public String getBrowserType(HttpServletRequest request) {
String browser = "";
String userAgent = request.getHeader("User-Agent");
logMsg("user-agent:" + userAgent);
if (userAgent.indexOf("Trident") > 0 || userAgent.indexOf("MSIE") > 0) {
browser = "IE";
}
else if (userAgent.indexOf("Opera") > 0) {
browser = "OPERA";
}
else if (userAgent.indexOf("Firefox") > 0) {
browser = "FIREFOX";
}
else if (userAgent.indexOf("Safari") > 0) {
if (userAgent.indexOf("Chrome") > 0) {
browser = "CHROME";
}
else {
browser = "SAFARI";
}
}
return browser;
}
public String getContextRootPath(HttpServletRequest request)
{
String contextRootDirAbsolutePath = "";
String resPath = "";
String temPath = "";
ServletContext context = request.getServletContext();
// get context real path
contextRootDirAbsolutePath = context.getRealPath("/");
// Spring Boot에서는 getRealPath()로 값을 구할 수 없으므로 다른방식으로 구해줌
if (contextRootDirAbsolutePath == null) {
temPath = XDrmUtil.class.getProtectionDomain().getCodeSource().getLocation().getPath();
// 앞에 붙은 file:/를 삭제
resPath = temPath.substring(temPath.indexOf(":") + 2);
resPath = resPath.substring(0, resPath.lastIndexOf("/"));
resPath = resPath.substring(0, resPath.lastIndexOf("/"));
resPath = resPath.substring(0, resPath.lastIndexOf("/"));
resPath = resPath.substring(0, resPath.lastIndexOf(".")); // 폴더 이름으로 사용하기 위해 파일 확장자 제거
resPath += "/";
contextRootDirAbsolutePath = resPath;
}
return contextRootDirAbsolutePath;
}
// get a file upload process
private ServletFileUpload getFileUploadProcessor()
{
// create a new file item factory
DiskFileItemFactory factory = new DiskFileItemFactory();
// create a new file object for a temporary directory
File tempDir = new File(tempDirAbsolutePath);
// create a temporary directory
if (!tempDir.exists()) {
tempDir.mkdirs();
}
// set a temporary directory
factory.setRepository(tempDir);
// set a maximum memory file size
factory.setSizeThreshold(maxMemoryFileSize);
// create a servlet file upload object using a factory
ServletFileUpload upload = new ServletFileUpload(factory);
// set a maixmum file size
upload.setSizeMax(maxFileSize);
// set header encoding characterset for hangul file name
upload.setHeaderEncoding("UTF-8");
return upload;
}
// 임시 파일 이름 생성하여 리턴
private String getRandomFileName()
{
return java.util.UUID.randomUUID().toString().replace("-", "");
}
// 파일 절대 경로를 이용하여 디렉토리 생성
public void makeDirUsingFilePath(String fileAbsolutePath)
{
File oFile = new File(fileAbsolutePath);
File oDir = oFile.getParentFile();
// create a diectory
if (!oDir.exists()) {
oDir.mkdirs();
}
}
// 파일 절대 경로에 해당하는 파일 삭제
public boolean deleteFile(String fileAbsolutePath)
{
boolean bDeleteSuccess = false;
File file;
try {
file = new File(fileAbsolutePath);
// 파일이 존재할 경우, 파일 삭제 처리
if (file.exists()) {
bDeleteSuccess = file.delete();
}
}
catch (Exception e) {
logMsg("deleteUploadFile e = " + e.getMessage());
}
catch (Throwable ex) {
logMsg("deleteUploadFile ex = " + ex.getMessage());
}
return bDeleteSuccess;
}
// temp 폴더 파일 삭제 되었는지 체크 후 로그 출력
public void checkTempFileDeleted(FileItem fileItem)
{
String tempFileAbsolutePath = "";
File tempFile = null;
String tempFileName;
DeferredFileOutputStream dfos = null;
try {
dfos = (DeferredFileOutputStream)fileItem.getOutputStream();
tempFileName = dfos.getFile().getName(); // temp 폴더 파일의 이름 구하기
tempFileAbsolutePath = tempDirAbsolutePath + File.separator + tempFileName;
tempFile = new File(tempFileAbsolutePath);
if (tempFile.exists()) {
// 파일이 존재할 경우 삭제 실패 한 것
logMsg("Failed to delete file in the temp folder, path = " + tempFileAbsolutePath);
}
else {
logMsg("Successfully delete files in the temp folder, path = " + tempFileAbsolutePath);
}
}
catch (Exception e) {
logMsg("checkTempFile e = " + e.getMessage());
}
catch (Throwable ex) {
logMsg("checkTempFile ex = " + ex.getMessage());
}
finally {
if (dfos != null) {
try { dfos.close(); }
catch (Exception ignore) {}
}
}
}
// FileItem에 대한 파일 데이터를 파일로 저장하고, FileItem 값 삭제 및 저장된 파일 경로 반환
public String handleUploadFile(FileItem fileItem, HashMap paramMap) throws Exception, Throwable
{
// FileItem의 파일 데이터를 저장할 파일 절대 경로
String saveFileAbsolutePath = "";
// FileItem에 저장된 HTML FILE NAME을 구함
String filePath = fileItem.getName();
fileName = FilenameUtils.getName(filePath);
String fileNameExt = FilenameUtils.getExtension(fileName);
logMsg("filePath = " + filePath);
logMsg("fileName = " + fileName);
logMsg("fileNameExt = " + fileNameExt);
logMsg("getContentType = " + fileItem.getContentType());
logMsg("getSize = " + fileItem.getSize());
// 파일 저장 디렉토리 절대 경로(saveBaseDirAbsolutePath) 및 랜덤 파일 이름을 생성하여 저장할 파일 경로를 설정
saveFileAbsolutePath = saveBaseDirAbsolutePath + File.separator + getRandomFileName();
logMsg("saveFileAbsolutePath = " + saveFileAbsolutePath);
// 저장 파일 절대 경로를 이용하여 디렉토리 생성
makeDirUsingFilePath(saveFileAbsolutePath);
// 파일에 대한 fileItem 값을 파일에 저장, 오류 발생시 5회 반복
while (true) {
int retryCount = 0;
try {
// FileItem의 파일 데이터를 파일로 저장
fileItem.write(new File(saveFileAbsolutePath));
break;
}
catch (Exception e) {
logMsg("Exception Msg = " + e.getMessage());
retryCount++;
if (retryCount > 5) {
logMsg("Fail to wirte a file");
errorMsg = "Fail to wirte a file";
// 파일이 존재할 경우, 파일 삭제 처리
deleteFile(saveFileAbsolutePath);
return null;
}
else {
try { Thread.sleep(1000); }
catch (InterruptedException ignore) { }
continue;
}
}
}
logMsg("Success To Write File");
// File 아이템의 파일 데이터 값 삭제 처리
fileItem.delete();
// temp 폴더의 임시파일 삭제 유무 로그 출력
checkTempFileDeleted(fileItem);
// 저장돤 파일 절대 경로 반환
return saveFileAbsolutePath;
}
}