Merge branch 'master' of http://docs.nculture.org:30000/nculture/iams.nlib
This commit is contained in:
commit
d381766124
7
pom.xml
7
pom.xml
@ -385,6 +385,13 @@
|
|||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
<version>3.3.2</version>
|
<version>3.3.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- OWASP HTML Sanitizer -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.googlecode.owasp-java-html-sanitizer</groupId>
|
||||||
|
<artifactId>owasp-java-html-sanitizer</artifactId>
|
||||||
|
<version>20211018.2</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|||||||
@ -1,327 +1,322 @@
|
|||||||
package nlib.cmm.fileupload;
|
package nlib.cmm.fileupload;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.security.access.annotation.Secured;
|
import org.springframework.security.access.annotation.Secured;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
import nlib.bbs.service.AttachFileService;
|
import nlib.bbs.service.AttachFileService;
|
||||||
import nlib.bbs.service.AttachFileVO;
|
import nlib.bbs.service.AttachFileVO;
|
||||||
import nlib.cmm.NlibCommonController;
|
import nlib.cmm.NlibCommonController;
|
||||||
import nlib.cmm.exception.ErrorMessage;
|
import nlib.cmm.exception.ErrorMessage;
|
||||||
import nlib.cmm.service.NlibProperty;
|
import nlib.cmm.service.NlibProperty;
|
||||||
import nlib.util.FileUtil;
|
import nlib.util.FileUtil;
|
||||||
import nlib.util.StringUtil;
|
import nlib.util.StringUtil;
|
||||||
import nlib.util.UUID;
|
import nlib.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <pre>
|
* <pre>
|
||||||
* @Class Name : FileUploadController.java
|
* @Class Name : FileUploadController.java
|
||||||
*
|
*
|
||||||
* @Description : 파일 업로드를 처리하는 컨트롤러
|
* @Description : 파일 업로드를 처리하는 컨트롤러
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
|
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @ ------------ -------- ---------------------------
|
* @ ------------ -------- ---------------------------
|
||||||
* @ 수정일 수정자 수정내용
|
* @ 수정일 수정자 수정내용
|
||||||
* @ ------------ -------- ---------------------------
|
* @ ------------ -------- ---------------------------
|
||||||
* @ 2021. 7. 15. KNKIM 최초 생성
|
* @ 2021. 7. 15. KNKIM 최초 생성
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @author 이씨플라자 * DIGITALSHIP KNKIM
|
* @author 이씨플라자 * DIGITALSHIP KNKIM
|
||||||
* @since 2021. 7. 15.
|
* @since 2021. 7. 15.
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Controller
|
@Controller
|
||||||
public class FileUploadController extends NlibCommonController {
|
public class FileUploadController extends NlibCommonController {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(FileUploadController.class);
|
private static final Logger log = LoggerFactory.getLogger(FileUploadController.class);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 첨부파일이 저장되는 최상위 위치
|
* 첨부파일이 저장되는 최상위 위치
|
||||||
*/
|
*/
|
||||||
private String FILEUPLOAD_BASE_PATH = NlibProperty.getProperty("fileupload.base.path");
|
private String FILEUPLOAD_BASE_PATH = NlibProperty.getProperty("fileupload.base.path");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 첨부파일 임시 저장 위치
|
* 경로 부적합 오류 메시지
|
||||||
*/
|
*/
|
||||||
private String FILEUPLOAD_TEMP_SUBPATH = NlibProperty.getProperty("fileupload.temp.subpath");
|
private static final String MSG_NOT_VALID_FILE_PATH = "파일 경로가 부적합합니다. 관리자에게 문의하여 주시기 바랍니다.";
|
||||||
|
|
||||||
/**
|
|
||||||
* 경로 부적합 오류 메시지
|
@Resource(name="attachFileService")
|
||||||
*/
|
private AttachFileService attachFileService;
|
||||||
private static final String MSG_NOT_VALID_FILE_PATH = "파일 경로가 부적합합니다. 관리자에게 문의하여 주시기 바랍니다.";
|
|
||||||
|
/**
|
||||||
|
* 파일업로드(Ajax) 처리
|
||||||
@Resource(name="attachFileService")
|
* - 화면 : Javascript Free Open Framework DropZone 사용
|
||||||
private AttachFileService attachFileService;
|
*
|
||||||
|
* @param multiRequest
|
||||||
/**
|
* @param subPathKey
|
||||||
* 파일업로드(Ajax) 처리
|
* @param response : 파일정보를 담은 JSON String
|
||||||
* - 화면 : Javascript Free Open Framework DropZone 사용
|
* @return
|
||||||
*
|
*/
|
||||||
* @param multiRequest
|
@Secured("ROLE_USER")
|
||||||
* @param subPathKey
|
@ResponseBody
|
||||||
* @param response : 파일정보를 담은 JSON String
|
@RequestMapping(value="/fileupload/uploadFilesAjax.do", produces="application/json")
|
||||||
* @return
|
public ResponseEntity uploadFilesAjax(
|
||||||
*/
|
final MultipartHttpServletRequest multiRequest
|
||||||
@Secured("ROLE_USER")
|
, @RequestParam(name="subPathKey") String subPathKey
|
||||||
@ResponseBody
|
, HttpServletResponse response) {
|
||||||
@RequestMapping(value="/fileupload/uploadFilesAjax.do", produces="application/json")
|
|
||||||
public ResponseEntity uploadFilesAjax(
|
String message = null;
|
||||||
final MultipartHttpServletRequest multiRequest
|
|
||||||
, @RequestParam(name="subPathKey") String subPathKey
|
// TODO : 권한 체크 추가할 것
|
||||||
, HttpServletResponse response) {
|
List<AttachFileVO> result = new ArrayList<AttachFileVO>();
|
||||||
|
|
||||||
String message = null;
|
try {
|
||||||
|
|
||||||
// TODO : 권한 체크 추가할 것
|
// 최상위 위치
|
||||||
List<AttachFileVO> result = new ArrayList<AttachFileVO>();
|
if(FileUtil.isEmpty(FILEUPLOAD_BASE_PATH)) {
|
||||||
|
message = "첨부파일이 저장되는 최상위 위치정보값이 정확하지 않습니다.";
|
||||||
try {
|
log.error(message + " : FILEUPLOAD_BASE_PATH 값 부재");
|
||||||
|
ErrorMessage errorMessage = new ErrorMessage("ERROR", message);
|
||||||
// 최상위 위치
|
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage);
|
||||||
if(FileUtil.isEmpty(FILEUPLOAD_BASE_PATH)) {
|
}
|
||||||
message = "첨부파일이 저장되는 최상위 위치정보값이 정확하지 않습니다.";
|
|
||||||
log.error(message + " : FILEUPLOAD_BASE_PATH 값 부재");
|
// 서브 위치
|
||||||
ErrorMessage errorMessage = new ErrorMessage("ERROR", message);
|
if(StringUtil.isEmpty(subPathKey)) {
|
||||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage);
|
message = "첨부파일이 저장되는 하위 위치정보값이 정확하지 않습니다.";
|
||||||
}
|
log.error(message + " : 매개변수 subPathKey 값 부재");
|
||||||
|
ErrorMessage errorMessage = new ErrorMessage("ERROR", message);
|
||||||
// 서브 위치
|
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage);
|
||||||
if(StringUtil.isEmpty(subPathKey)) {
|
}
|
||||||
message = "첨부파일이 저장되는 하위 위치정보값이 정확하지 않습니다.";
|
String subPath = NlibProperty.getProperty(subPathKey);
|
||||||
log.error(message + " : 매개변수 subPathKey 값 부재");
|
if(StringUtil.isEmpty(subPath)) {
|
||||||
ErrorMessage errorMessage = new ErrorMessage("ERROR", message);
|
message = "첨부파일이 저장되는 하위 위치정보값을 찾을 수 없습니다.";
|
||||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage);
|
log.error(message + " : 매개변수 subPathKey의 속성값 부재");
|
||||||
}
|
ErrorMessage errorMessage = new ErrorMessage("ERROR", message);
|
||||||
String subPath = NlibProperty.getProperty(subPathKey);
|
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage);
|
||||||
if(StringUtil.isEmpty(subPath)) {
|
}
|
||||||
message = "첨부파일이 저장되는 하위 위치정보값을 찾을 수 없습니다.";
|
|
||||||
log.error(message + " : 매개변수 subPathKey의 속성값 부재");
|
// 위치정보 적합 확인
|
||||||
ErrorMessage errorMessage = new ErrorMessage("ERROR", message);
|
if(FileUtil.isNotValid(FILEUPLOAD_BASE_PATH + subPath)) {
|
||||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage);
|
message = MSG_NOT_VALID_FILE_PATH;
|
||||||
}
|
log.error(message + " : " + (FILEUPLOAD_BASE_PATH + subPath));
|
||||||
|
ErrorMessage errorMessage = new ErrorMessage("ERROR", message);
|
||||||
// 위치정보 적합 확인
|
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage);
|
||||||
if(FileUtil.isNotValid(FILEUPLOAD_BASE_PATH + subPath)) {
|
}
|
||||||
message = MSG_NOT_VALID_FILE_PATH;
|
|
||||||
log.error(message + " : " + (FILEUPLOAD_BASE_PATH + subPath));
|
// 파일 업로드 처리
|
||||||
ErrorMessage errorMessage = new ErrorMessage("ERROR", message);
|
final Map<String, MultipartFile> files = multiRequest.getFileMap();
|
||||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage);
|
log.debug("uploadFilesAjax : 진입 > 파일수 = " + (files == null ? " files null " : files.size()));
|
||||||
}
|
|
||||||
|
File dir = new File(FILEUPLOAD_BASE_PATH + subPath);
|
||||||
// 파일 업로드 처리
|
if(!dir.exists() || !dir.isDirectory()) dir.mkdirs();
|
||||||
final Map<String, MultipartFile> files = multiRequest.getFileMap();
|
|
||||||
log.debug("uploadFilesAjax : 진입 > 파일수 = " + (files == null ? " files null " : files.size()));
|
if(!files.isEmpty()) {
|
||||||
|
|
||||||
File dir = new File(FILEUPLOAD_BASE_PATH + subPath);
|
Iterator<Entry<String, MultipartFile>> itr = files.entrySet().iterator();
|
||||||
if(!dir.exists() || !dir.isDirectory()) dir.mkdirs();
|
MultipartFile file;
|
||||||
|
String filePath = "";
|
||||||
if(!files.isEmpty()) {
|
AttachFileVO atvo;
|
||||||
|
|
||||||
Iterator<Entry<String, MultipartFile>> itr = files.entrySet().iterator();
|
// 허용 파일 확장자
|
||||||
MultipartFile file;
|
String acceptableExtList = StringUtil.getString(NlibProperty.getString("fileupload.acceptable.ext"), null);
|
||||||
String filePath = "";
|
if(acceptableExtList != null) acceptableExtList = "," + acceptableExtList.trim().toLowerCase();
|
||||||
AttachFileVO atvo;
|
boolean acceptableExt = false;
|
||||||
|
|
||||||
// 허용 파일 확장자
|
// 최대 파일크기
|
||||||
String acceptableExtList = StringUtil.getString(NlibProperty.getString("fileupload.acceptable.ext"), null);
|
int maxFileSize = NlibProperty.getInt("fileupload.max.mbsize", 10) * 1024 * 1024;
|
||||||
if(acceptableExtList != null) acceptableExtList = "," + acceptableExtList.trim().toLowerCase();
|
|
||||||
boolean acceptableExt = false;
|
// 최대 개수
|
||||||
|
int maxFileCount = NlibProperty.getInt("fileupload.max.files", 5);
|
||||||
// 최대 파일크기
|
|
||||||
int maxFileSize = NlibProperty.getInt("fileupload.max.mbsize", 10) * 1024 * 1024;
|
while (itr.hasNext()) {
|
||||||
|
|
||||||
// 최대 개수
|
if(result.size() >= maxFileCount) {
|
||||||
int maxFileCount = NlibProperty.getInt("fileupload.max.files", 5);
|
log.error("최대 개수를 초과하여 이후 파일은 처리되지 않습니다.");
|
||||||
|
break;
|
||||||
while (itr.hasNext()) {
|
}
|
||||||
|
|
||||||
if(result.size() >= maxFileCount) {
|
acceptableExt = false;
|
||||||
log.error("최대 개수를 초과하여 이후 파일은 처리되지 않습니다.");
|
|
||||||
break;
|
Entry<String, MultipartFile> entry = itr.next();
|
||||||
}
|
|
||||||
|
file = entry.getValue();
|
||||||
acceptableExt = false;
|
String orignlFileNm = file.getOriginalFilename();
|
||||||
|
|
||||||
Entry<String, MultipartFile> entry = itr.next();
|
//--------------------------------------
|
||||||
|
// 원 파일명이 없는 경우 처리 SKIP
|
||||||
file = entry.getValue();
|
// (첨부가 되지 않은 input file type)
|
||||||
String orignlFileNm = file.getOriginalFilename();
|
//--------------------------------------
|
||||||
|
if (orignlFileNm == null || "".equals(orignlFileNm)) {
|
||||||
//--------------------------------------
|
continue;
|
||||||
// 원 파일명이 없는 경우 처리 SKIP
|
}
|
||||||
// (첨부가 되지 않은 input file type)
|
|
||||||
//--------------------------------------
|
// 파일 확장자
|
||||||
if (orignlFileNm == null || "".equals(orignlFileNm)) {
|
int index = orignlFileNm.lastIndexOf(".");
|
||||||
continue;
|
String fileExt = (index < 1 ? "" : orignlFileNm.substring(index + 1)).toLowerCase();
|
||||||
}
|
|
||||||
|
if(acceptableExtList != null) {
|
||||||
// 파일 확장자
|
|
||||||
int index = orignlFileNm.lastIndexOf(".");
|
if(acceptableExtList.contains("." + fileExt)) {
|
||||||
String fileExt = (index < 1 ? "" : orignlFileNm.substring(index + 1)).toLowerCase();
|
acceptableExt = true;
|
||||||
|
} else if(acceptableExtList.contains("image/*")) {
|
||||||
if(acceptableExtList != null) {
|
acceptableExt = ".jpg,.jpe,.jpge,.bmp,.gif,.png".contains("." + fileExt);
|
||||||
|
}
|
||||||
if(acceptableExtList.contains("." + fileExt)) {
|
}
|
||||||
acceptableExt = true;
|
if(!acceptableExt) {
|
||||||
} else if(acceptableExtList.contains("image/*")) {
|
log.error("허용되지 않는 파일 확장자 입니다. : " + orignlFileNm);
|
||||||
acceptableExt = ".jpg,.jpe,.jpge,.bmp,.gif,.png".contains("." + fileExt);
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if(!acceptableExt) {
|
int size = (int)file.getSize();
|
||||||
log.error("허용되지 않는 파일 확장자 입니다. : " + orignlFileNm);
|
if(size > maxFileSize) {
|
||||||
continue;
|
log.error("첨부파일이 허용 크기를 초과합니다. : " + orignlFileNm);
|
||||||
}
|
continue;
|
||||||
|
}
|
||||||
int size = (int)file.getSize();
|
|
||||||
if(size > maxFileSize) {
|
String streFileNm = UUID.getNewStreFileNm();
|
||||||
log.error("첨부파일이 허용 크기를 초과합니다. : " + orignlFileNm);
|
|
||||||
continue;
|
filePath = FILEUPLOAD_BASE_PATH + subPath + "/" + streFileNm;
|
||||||
}
|
log.debug("FILE UPLOAD : filePath=" + filePath);
|
||||||
|
|
||||||
String streFileNm = UUID.getNewStreFileNm();
|
file.transferTo(new File(FileUtil.filePathBlackList(filePath)));
|
||||||
|
|
||||||
filePath = FILEUPLOAD_BASE_PATH + subPath + "/" + streFileNm;
|
atvo = new AttachFileVO();
|
||||||
log.debug("FILE UPLOAD : filePath=" + filePath);
|
atvo.setSubPathKey(subPathKey);
|
||||||
|
//atvo.setAttachFileId(attachFileId); // 실제 DB 저장 처리될때 설정함
|
||||||
file.transferTo(new File(FileUtil.filePathBlackList(filePath)));
|
atvo.setStreFileNm(streFileNm);
|
||||||
|
atvo.setOrignlFileNm(orignlFileNm);
|
||||||
atvo = new AttachFileVO();
|
atvo.setFileExt(fileExt);
|
||||||
atvo.setSubPathKey(subPathKey);
|
atvo.setFileSize(size);
|
||||||
//atvo.setAttachFileId(attachFileId); // 실제 DB 저장 처리될때 설정함
|
|
||||||
atvo.setStreFileNm(streFileNm);
|
result.add(atvo);
|
||||||
atvo.setOrignlFileNm(orignlFileNm);
|
}
|
||||||
atvo.setFileExt(fileExt);
|
}
|
||||||
atvo.setFileSize(size);
|
} catch(SecurityException e) {
|
||||||
|
log.error("uploadFilesAjax SecurityException : " + e.toString());
|
||||||
result.add(atvo);
|
ErrorMessage errorMessage = new ErrorMessage("ERROR", "처리에 실패하였습니다(1)");
|
||||||
}
|
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage);
|
||||||
}
|
} catch(IllegalStateException e) {
|
||||||
} catch(SecurityException e) {
|
log.error("uploadFilesAjax IllegalStateException : " + e.toString());
|
||||||
log.error("uploadFilesAjax SecurityException : " + e.toString());
|
ErrorMessage errorMessage = new ErrorMessage("ERROR", "처리에 실패하였습니다(1)");
|
||||||
ErrorMessage errorMessage = new ErrorMessage("ERROR", "처리에 실패하였습니다(1)");
|
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage);
|
||||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage);
|
} catch(IOException e) {
|
||||||
} catch(IllegalStateException e) {
|
log.error("uploadFilesAjax IOException : " + e.toString());
|
||||||
log.error("uploadFilesAjax IllegalStateException : " + e.toString());
|
ErrorMessage errorMessage = new ErrorMessage("ERROR", "처리에 실패하였습니다(1)");
|
||||||
ErrorMessage errorMessage = new ErrorMessage("ERROR", "처리에 실패하였습니다(1)");
|
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage);
|
||||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage);
|
}
|
||||||
} catch(IOException e) {
|
|
||||||
log.error("uploadFilesAjax IOException : " + e.toString());
|
// Convert Json
|
||||||
ErrorMessage errorMessage = new ErrorMessage("ERROR", "처리에 실패하였습니다(1)");
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage);
|
String json;
|
||||||
}
|
try {
|
||||||
|
json = mapper.writeValueAsString(result);
|
||||||
// Convert Json
|
log.debug("RETURN DATA > json:" + json);
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
} catch (JsonProcessingException e) {
|
||||||
String json;
|
json = null;
|
||||||
try {
|
log.error("uploadFilesAjax Error : " + e.toString());
|
||||||
json = mapper.writeValueAsString(result);
|
ErrorMessage errorMessage = new ErrorMessage("ERROR", "JSON 변환 처리에 실패하였습니다 : " + e.toString());
|
||||||
log.debug("RETURN DATA > json:" + json);
|
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage);
|
||||||
} catch (JsonProcessingException e) {
|
}
|
||||||
json = null;
|
|
||||||
log.error("uploadFilesAjax Error : " + e.toString());
|
HttpHeaders responseHeaders = new HttpHeaders();
|
||||||
ErrorMessage errorMessage = new ErrorMessage("ERROR", "JSON 변환 처리에 실패하였습니다 : " + e.toString());
|
ResponseEntity ret = ResponseEntity.ok().headers(responseHeaders).body(json);
|
||||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage);
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpHeaders responseHeaders = new HttpHeaders();
|
/**
|
||||||
ResponseEntity ret = ResponseEntity.ok().headers(responseHeaders).body(json);
|
* 파일 다운로드를 처리한다.
|
||||||
return ret;
|
*
|
||||||
}
|
* @param params
|
||||||
|
* @param mv
|
||||||
/**
|
* @return
|
||||||
* 파일 다운로드를 처리한다.
|
* @throws Exception
|
||||||
*
|
*/
|
||||||
* @param params
|
@RequestMapping(value="/fileupload/downloadAttachFile.do")
|
||||||
* @param mv
|
public ModelAndView downloadAttachFile(HttpServletRequest request, AttachFileVO attachFileVO, ModelAndView mv) throws Exception {
|
||||||
* @return
|
|
||||||
* @throws Exception
|
//---------------------------------
|
||||||
*/
|
// 권한체크
|
||||||
@RequestMapping(value="/fileupload/downloadAttachFile.do")
|
//---------------------------------
|
||||||
public ModelAndView downloadAttachFile(HttpServletRequest request, AttachFileVO attachFileVO, ModelAndView mv) throws Exception {
|
// 공지사항, FAQ : 모두 공개
|
||||||
|
// QnA : 공개된 글인 경우, 모두 공개
|
||||||
//---------------------------------
|
// QnA : 비밀글 (본인에 한정)
|
||||||
// 권한체크
|
|
||||||
//---------------------------------
|
attachFileVO.setMbInfoId(getMbInfoId(request));
|
||||||
// 공지사항, FAQ : 모두 공개
|
boolean hasAuth = attachFileService.checkAttachFileDownload(attachFileVO);
|
||||||
// QnA : 공개된 글인 경우, 모두 공개
|
|
||||||
// QnA : 비밀글 (본인에 한정)
|
if(!hasAuth) {
|
||||||
|
throw new Exception("잘못된 접근입니다. 파일다운로드를 할 수 있는 권한이 없습니다.");
|
||||||
attachFileVO.setMbInfoId(getMbInfoId(request));
|
}
|
||||||
boolean hasAuth = attachFileService.checkAttachFileDownload(attachFileVO);
|
|
||||||
|
AttachFileVO retAttachFileVO = attachFileService.selectAttachFile(attachFileVO);
|
||||||
if(!hasAuth) {
|
|
||||||
throw new Exception("잘못된 접근입니다. 파일다운로드를 할 수 있는 권한이 없습니다.");
|
if(retAttachFileVO == null || StringUtil.isEmpty(retAttachFileVO.getAttachFileId())) {
|
||||||
}
|
throw new Exception("잘못된 접근이므로 파일다운로드를 할 수 없습니다.");
|
||||||
|
}
|
||||||
AttachFileVO retAttachFileVO = attachFileService.selectAttachFile(attachFileVO);
|
|
||||||
|
if(StringUtil.isEmpty(retAttachFileVO.getFileStrePath()) || StringUtil.isEmpty(retAttachFileVO.getStreFileNm())) {
|
||||||
if(retAttachFileVO == null || StringUtil.isEmpty(retAttachFileVO.getAttachFileId())) {
|
throw new Exception("파일정보가 올바르지 않습니다.");
|
||||||
throw new Exception("잘못된 접근이므로 파일다운로드를 할 수 없습니다.");
|
}
|
||||||
}
|
|
||||||
|
if(StringUtil.isEmpty(retAttachFileVO.getOrignlFileNm())) {
|
||||||
if(StringUtil.isEmpty(retAttachFileVO.getFileStrePath()) || StringUtil.isEmpty(retAttachFileVO.getStreFileNm())) {
|
retAttachFileVO.setOrignlFileNm("첨부파일." + retAttachFileVO.getFileExt());
|
||||||
throw new Exception("파일정보가 올바르지 않습니다.");
|
}
|
||||||
}
|
|
||||||
|
if(StringUtil.isEmpty(retAttachFileVO.getOrignlFileNm())) {
|
||||||
if(StringUtil.isEmpty(retAttachFileVO.getOrignlFileNm())) {
|
retAttachFileVO.setOrignlFileNm("첨부파일." + retAttachFileVO.getFileExt());
|
||||||
retAttachFileVO.setOrignlFileNm("첨부파일." + retAttachFileVO.getFileExt());
|
}
|
||||||
}
|
|
||||||
|
String fullPath = retAttachFileVO.getFileStrePath() + retAttachFileVO.getStreFileNm();
|
||||||
if(StringUtil.isEmpty(retAttachFileVO.getOrignlFileNm())) {
|
|
||||||
retAttachFileVO.setOrignlFileNm("첨부파일." + retAttachFileVO.getFileExt());
|
log.debug("downloadAttachFile > fullPath = " + fullPath);
|
||||||
}
|
|
||||||
|
if(FileUtil.isNotValid(fullPath)) {
|
||||||
String fullPath = retAttachFileVO.getFileStrePath() + retAttachFileVO.getStreFileNm();
|
throw new Exception(MSG_NOT_VALID_FILE_PATH);
|
||||||
|
}
|
||||||
log.debug("downloadAttachFile > fullPath = " + fullPath);
|
|
||||||
|
File file = new File(FileUtil.filePathBlackList(fullPath));
|
||||||
if(FileUtil.isNotValid(fullPath)) {
|
if(!file.isFile()) {
|
||||||
throw new Exception(MSG_NOT_VALID_FILE_PATH);
|
throw new Exception("해당 파일이 존재하지 않습니다. 관리자에게 문의하여 주시기 바랍니다.");
|
||||||
}
|
}
|
||||||
|
|
||||||
File file = new File(FileUtil.filePathBlackList(fullPath));
|
mv.setViewName("downloadView"); // dispatcher-servlet.xml내 BeanNameViewResolver 정의
|
||||||
if(!file.isFile()) {
|
mv.addObject("downloadFile", file);
|
||||||
throw new Exception("해당 파일이 존재하지 않습니다. 관리자에게 문의하여 주시기 바랍니다.");
|
mv.addObject("fname", retAttachFileVO.getOrignlFileNm());
|
||||||
}
|
|
||||||
|
return mv;
|
||||||
mv.setViewName("downloadView"); // dispatcher-servlet.xml내 BeanNameViewResolver 정의
|
}
|
||||||
mv.addObject("downloadFile", file);
|
|
||||||
mv.addObject("fname", retAttachFileVO.getOrignlFileNm());
|
}
|
||||||
|
|
||||||
return mv;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@ -13,6 +13,8 @@ import java.util.Base64.Encoder;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.owasp.html.HtmlPolicyBuilder;
|
||||||
|
import org.owasp.html.PolicyFactory;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -383,6 +385,33 @@ public class StringUtil extends StringUtils {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XSS 등의 공격으로 부터 보안성 유지를 위해서 HTML 허용된 태그와 속성만으로 HTML을 재구성하여 리턴한다.
|
||||||
|
*
|
||||||
|
* @param html
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static String sanitizeHtml(String html) {
|
||||||
|
|
||||||
|
PolicyFactory policy = new HtmlPolicyBuilder()
|
||||||
|
.allowAttributes("src", "align", "title").onElements("img")
|
||||||
|
.allowAttributes("href", "title").onElements("a")
|
||||||
|
.allowAttributes("class", "height", "width", "style").globally()
|
||||||
|
.allowUrlProtocols("http","https","mailto","tel")
|
||||||
|
.allowElements(
|
||||||
|
"a", "label",
|
||||||
|
"h1", "h2", "h3", "h4", "h5", "h6",
|
||||||
|
"p", "i", "b", "u", "strong", "em", "small", "big", "pre", "code",
|
||||||
|
"cite", "samp", "sub", "sup", "strike", "center", "blockquote",
|
||||||
|
"hr", "br", "col", "font", "span", "div", "img",
|
||||||
|
"ul", "ol", "li", "dd", "dt", "dl", "tbody", "thead", "tfoot",
|
||||||
|
"table", "td", "th", "tr", "colgroup", "fieldset", "legend"
|
||||||
|
)
|
||||||
|
.toFactory();
|
||||||
|
|
||||||
|
return policy.sanitize(html);
|
||||||
|
}
|
||||||
|
|
||||||
// Tag 화이트 리스트 ( 허용할 태그 등록 )
|
// Tag 화이트 리스트 ( 허용할 태그 등록 )
|
||||||
static String[] whiteListTag = { "<p>","</p>","<br />" };
|
static String[] whiteListTag = { "<p>","</p>","<br />" };
|
||||||
|
|
||||||
|
|||||||
@ -108,6 +108,9 @@ fileupload.base.path = /nfs_nas_dev/uac/nlib
|
|||||||
# \uc6b4\uc601\uc11c\ubc84
|
# \uc6b4\uc601\uc11c\ubc84
|
||||||
#fileupload.base.path = /nfs_nas/uac/nlib
|
#fileupload.base.path = /nfs_nas/uac/nlib
|
||||||
|
|
||||||
|
# \ubb3b\uace0\ub2f5\ud558\uae30 \uac8c\uc2dc\ud310 \uc11c\ube0c\uc704\uce58 : \ucca8\ubd80\ud30c\uc77c \ucd5c\uc0c1\uc704 \uc704\uce58 \uc774\ud558\uc758 \uc704\uce58 \uc815\ubcf4\ub97c \uc124\uc815
|
||||||
|
fileupload.bbs.qna.subpath = /qna
|
||||||
|
|
||||||
# \ucd5c\ub300 \ud30c\uc77c \ud06c\uae30 (MB)
|
# \ucd5c\ub300 \ud30c\uc77c \ud06c\uae30 (MB)
|
||||||
fileupload.max.mbsize = 10
|
fileupload.max.mbsize = 10
|
||||||
# \ucd5c\ub300 \ud30c\uc77c \uac1c\uc218
|
# \ucd5c\ub300 \ud30c\uc77c \uac1c\uc218
|
||||||
@ -116,12 +119,6 @@ fileupload.max.files = 5
|
|||||||
fileupload.acceptable.ext = .jpg,.jpe,.jpge,.bmp,.gif,.png,.hwp,.hwpx,.pdf,.xls,.xlsx,.ppt,.pptx,.doc,.docx,.txt
|
fileupload.acceptable.ext = .jpg,.jpe,.jpge,.bmp,.gif,.png,.hwp,.hwpx,.pdf,.xls,.xlsx,.ppt,.pptx,.doc,.docx,.txt
|
||||||
|
|
||||||
|
|
||||||
# \uc784\uc2dc \uc800\uc7a5 \uc704\uce58
|
|
||||||
fileupload.temp.subpath = /temp
|
|
||||||
|
|
||||||
# \ubb3b\uace0\ub2f5\ud558\uae30 \uac8c\uc2dc\ud310 \uc11c\ube0c\uc704\uce58 : \ucca8\ubd80\ud30c\uc77c \ucd5c\uc0c1\uc704 \uc704\uce58 \uc774\ud558\uc758 \uc704\uce58 \uc815\ubcf4\ub97c \uc124\uc815
|
|
||||||
fileupload.bbs.qna.subpath = /qna
|
|
||||||
|
|
||||||
#----------------------------------------
|
#----------------------------------------
|
||||||
# \uc774\uba54\uc77c \ud15c\ud50c\ub9bf \uacbd\ub85c
|
# \uc774\uba54\uc77c \ud15c\ud50c\ub9bf \uacbd\ub85c
|
||||||
#----------------------------------------
|
#----------------------------------------
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user