
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
package froala.editor;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import egovframework.com.cmm.util.EgovResourceCloseHelper;
import egovframework.rte.fdl.cmmn.exception.EgovBizException;
import froala.editor.file.FileOptions;
import froala.editor.image.ImageOptions;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.Thumbnails.Builder;
/**
* File functionality.
*
* @author florin@froala.com
*/
@Component
public final class File {
private static final Logger LOGGER = LoggerFactory.getLogger(File.class);
/**
* Content type string used in http multipart.
*/
public static final String multipartContentType = "multipart/form-data";
/**
* Private constructor.
*/
private File() {
}
/**
* File default options.
*/
public static final FileOptions defaultOptions = new FileOptions();
/**
* Uploads a file to disk.
*
* @param req
* Servlet HTTP request.
* @param fileRoute
* Route Server route where the file will be uploaded. This route
* must be public to be accesed by the editor.
* @return Object with link.
* @throws EgovBizException
*/
public static EditorFileVO upload(HttpServletRequest req, String fileRoute) throws EgovBizException {
return upload(req, fileRoute, defaultOptions);
}
/**
* Uploads a file to disk.
*
* @param req
* Servlet HTTP request.
* @param fileRoute
* Server route where the file will be uploaded. This route must
* be public to be accesed by the editor.
* @param options
* File options. Defaults to {@link #defaultOptions} which has
* </br>
* Fieldname: "file" </br>
* Validation:
* <ul>
* <li>Extensions: "txt", "pdf", "doc"</li>
* <li>Mime Types: "text/plain", "application/msword",
* "application/x-pdf", "application/pdf"</li>
* </ul>
* @return Object with link.
* @throws EgovBizException
*/
public static EditorFileVO upload(HttpServletRequest req, String fileRoute, FileOptions options) throws EgovBizException {
if (options == null) {
options = defaultOptions;
}
if (req.getContentType() == null || req.getContentType().toLowerCase().indexOf(multipartContentType) == -1) {
throw new EgovBizException("Invalid contentType. It must be " + multipartContentType);
}
MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest)req;
MultipartFile file = multipartHttpServletRequest.getFile(options.getFieldname());
// servlet 3.0
//Part filePart = req.getPart(options.getFieldname());
if (file == null) {
throw new EgovBizException("Fieldname is not correct. It must be: " + options.getFieldname());
}
// Generate random name.
String file_extsn = FilenameUtils.getExtension(Utils.getFileName(file)).toLowerCase();
String extension = file_extsn;
extension = (extension != null && extension != "") ? "." + extension : extension;
String name;
try {
name = Utils.generateUniqueString() + extension;
} catch (NoSuchAlgorithmException e) {
// return null;
throw new EgovBizException("NoSuchAlgorithmException!");
}
String fullPath = fileRoute + name;
InputStream fileContent;
try {
fileContent = file.getInputStream();
} catch (IOException e) {
throw new EgovBizException("IOException!");
}
String absoluteServerPath = getAbsoluteServerPath(req, fullPath);
// String absoluteServerPath = linkName;
java.io.File targetFile = null;
if (absoluteServerPath != null && !absoluteServerPath.equals("")) {
targetFile = new java.io.File(absoluteServerPath);
} else {
return null;
}
// Resize image.
if (options instanceof ImageOptions && ((ImageOptions) options).getResizeOptions() != null) {
ImageOptions.ResizeOptions imageOptions = ((ImageOptions) options).getResizeOptions();
Builder<? extends InputStream> thumbnailsBuilder = Thumbnails.of(fileContent);
// Check aspect ratio.
int newWidth = imageOptions.getNewWidth();
int newHeight = imageOptions.getNewHeight();
if (imageOptions.getKeepAspectRatio()) {
thumbnailsBuilder = thumbnailsBuilder.size(newWidth, newHeight);
} else {
thumbnailsBuilder = thumbnailsBuilder.forceSize(newWidth, newHeight);
}
try {
thumbnailsBuilder.toFile(targetFile);
} catch (IOException e) {
LOGGER.error(e.getCause().getMessage());
}
} else {
try {
FileUtils.copyInputStreamToFile(fileContent, targetFile);
} catch (IOException e) {
LOGGER.error(e.getCause().getMessage());
}
}
if (options.getValidation() != null
&& !options.getValidation().check(absoluteServerPath, file.getContentType())) {
delete(req, fullPath);
throw new EgovBizException("File does not meet the validation.");
}
// 정보 셋팅
EditorFileVO fileVO = new EditorFileVO();
fileVO.setLink(options.getDownloadUrl());
fileVO.setFullPath(fullPath);
fileVO.setFileExtsn(file_extsn);
fileVO.setOriginFileNm(file.getOriginalFilename());
fileVO.setSysFileNm(name);
fileVO.setUploadDir(fileRoute);
fileVO.setFileSize(file.getSize());
fileVO.setMime(file.getContentType());
return fileVO;
}
/**
* Get absolute server path.
*
* @param req
* Used to get the servlet context.
* @param relativePath
* Relative path.
* @return Absolute path.
*/
public static String getAbsoluteServerPath(HttpServletRequest req, String relativePath) {
// return req.getServletContext().getRealPath(relativePath);
return relativePath;
}
/**
* Delete a file from disk.
*
* @param req
* Used to get the servlet context.
* @param src
* Server file path.
*/
public static void delete(HttpServletRequest req, String src) {
String filePath = getAbsoluteServerPath(req, src);
java.io.File file = new java.io.File(filePath);
if (file.exists()) {
file.delete();
}
}
/**
* 압축파일(zip) 파일 업로드 - 압축해제 후 저장
* @param req
* @param fileRoute
* @param options
* @return
* @throws EgovBizException
* @throws NoSuchAlgorithmException
*/
public static List<EditorFileVO> zipUpload(HttpServletRequest req, String fileRoute, FileOptions options)
throws EgovBizException, NoSuchAlgorithmException {
if (options == null) {
options = defaultOptions;
}
if (req.getContentType() == null || req.getContentType().toLowerCase().indexOf(multipartContentType) == -1) {
throw new EgovBizException("Invalid contentType. It must be " + multipartContentType);
}
MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) req;
MultipartFile file = multipartHttpServletRequest.getFile(options.getFieldname());
if (file == null) {
throw new EgovBizException("Fieldname is not correct. It must be: " + options.getFieldname());
}
List<EditorFileVO> fileMap = new ArrayList<>();
ZipArchiveInputStream zin = null;
ZipArchiveEntry entry = null;
try {
zin = new ZipArchiveInputStream(file.getInputStream(), "EUC-KR", false);
java.io.File dir = new java.io.File(fileRoute);
dir.setExecutable(true);
dir.setReadable(true);
dir.setWritable(true);
if (!dir.exists()) {
boolean result = false;
try{
dir.mkdirs();
result = true;
}
catch(SecurityException se){
LOGGER.error("fail to process create Dir {}", se);
}
if(result) {
LOGGER.info("Dir created");
}
}
try {
while ((entry = zin.getNextZipEntry()) != null) {
// Generate random name.
String file_extsn = FilenameUtils.getExtension(entry.getName());
String extension = file_extsn;
extension = (extension != null && extension != "") ? "." + extension : extension;
String sysFileNm = Utils.generateUniqueString() + extension;
String fullPath = fileRoute + sysFileNm;
Path source = Paths.get(fullPath);
OutputStream zout = null;
try {
zout = new FileOutputStream(source.toFile());
//버퍼
byte[] buf = new byte[1024];
int len;
while ((len = zin.read(buf)) > 0) {
zout.write(buf, 0, len);
}
// 정보 셋팅
EditorFileVO fileVO = new EditorFileVO();
fileVO.setLink(options.getDownloadUrl());
fileVO.setFullPath(fullPath);
fileVO.setFileExtsn(file_extsn);
fileVO.setOriginFileNm(entry.getName());
fileVO.setSysFileNm(sysFileNm);
fileVO.setUploadDir(fileRoute);
fileVO.setFileSize(entry.getSize());
fileVO.setMime(Files.probeContentType(source));
fileMap.add(fileVO);
} catch (IOException e) {
LOGGER.error("fail to process zipUpload File {}", e);
} finally {
EgovResourceCloseHelper.close(zout);
}
}
} catch (IOException e) {
LOGGER.error("fail to process zipUpload File {}", e);
} finally {
EgovResourceCloseHelper.close(zin);
}
} catch (IOException e) {
LOGGER.error("fail to process zipUpload File {}", e);
}
return fileMap;
}
/**
* 디렉토리 하위파일 및 디렉토리 삭제
* @param path
*/
public static void deleteDirFileFn(String path) {
java.io.File file = new java.io.File(path); // 매개변수로 받은 경로를 파일객체선언 (/home/nation909/test 경로의 폴더를 지정함)
java.io.File[] files = file.listFiles(); // 해당 폴더 안의 파일들을 files 변수에 담음
if(files.length > 0) { // 파일, 폴더가 1개라도 있을경우 실행
for (int i=0; i<files.length; i++) { // 개수만큼 루프
if(files[i].isFile()) { // 파일일경우 해당파일 삭제
files[i].delete();
}
else { // 폴더일경우 재귀함수로 해당폴더의 경로를 전달함
deleteDirFileFn(files[i].getPath()); // 재귀함수
}
files[i].delete(); // 폴더일경우 재귀함수가 다돌고나서, 즉 폴더안의 파일이 다지워지고 나서 해당폴더를 삭제함
}
file.delete();
}
}
/**
* 파일을 복사하여 복사한 파일 정보를 리턴
* @param tempFile
* - 복사할 파일 VO 정보
* @param copyPath
* - 복사할 디렉토리 위치 정보
* @param options
* - 파일 옵션
* @return
* @throws IOException
*/
public static EditorFileVO fileCopy(EditorFileVO tempFile, String copyPath, FileOptions options) throws IOException {
java.io.File file = new java.io.File(tempFile.getFullPath());
java.io.File mfile = null;
String copyFullPath = "";
if(file.exists()) {
java.io.File directory = new java.io.File(copyPath);
directory.setExecutable(true);
directory.setReadable(true);
directory.setWritable(true);
if (!directory.exists()) {
boolean result = false;
try{
directory.mkdirs();
result = true;
}
catch(SecurityException se){
LOGGER.error("fail to process fileCopy create Dir {}", se);
}
if(result) {
LOGGER.info("Dir created");
}
}
copyFullPath = copyPath + tempFile.getSysFileNm();
mfile = new java.io.File(copyFullPath);
}
InputStream inStream = null;
OutputStream outStream = null;
EditorFileVO vo = null;
try{
inStream = new FileInputStream(file); //원본파일
outStream = new FileOutputStream(mfile); //이동시킬 위치
byte[] buffer = new byte[1024];
int length;
while ((length = inStream.read(buffer)) > 0){
outStream.write(buffer, 0, length);
}
vo = new EditorFileVO();
vo.setLink(options.getDownloadUrl());
vo.setFullPath(copyFullPath);
vo.setFileExtsn(tempFile.getFileExtsn());
vo.setOriginFileNm(tempFile.getOriginFileNm());
vo.setSysFileNm(tempFile.getSysFileNm());
vo.setUploadDir(copyPath);
vo.setFileSize(tempFile.getFileSize());
vo.setMime(tempFile.getMime());
} catch(IOException e) {
LOGGER.error("fail to process fileCopy {}", e);
} finally {
EgovResourceCloseHelper.close(inStream, outStream);
}
return vo;
}
/**
* List 파일객체를 받아 다수의 파일을 압축파일로 압축 후 다운로드
* @param req
* - HttpServletRequest
* @param res
* - HttpServletResponse
* @param fileList
* - 파일 정보를 담은 객체
* @param fileRoute
* - 파일을 저장할 경로
* @throws EgovBizException
*/
public static void zipDown(HttpServletRequest req
, HttpServletResponse res
, List<EditorFileVO> fileList
, String fileRoute) throws EgovBizException {
//추가 temp 경로 생성
String zipFilePath = Utils.getAddTempRoute(fileRoute);
// 파일명 생성 시 날짜
Calendar cal = Calendar.getInstance();
//현재 년도, 월, 일
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH) + 1;
int date = cal.get(Calendar.DATE);
String downloadFileName = year + "_" + month + "_" + date;
String zipFileNm = downloadFileName + ".zip";
String fullPath = zipFilePath + zipFileNm;
java.io.File file = new java.io.File(fullPath);
try {
//디렉토리 가져오기
java.io.File dir = new java.io.File(zipFilePath);
dir.setExecutable(true);
dir.setReadable(true);
dir.setWritable(true);
if (!dir.exists()) {
boolean result = false;
try{
dir.mkdirs();
result = true;
}
catch(SecurityException se){
LOGGER.error("fail to process create Dir {}", se);
}
if(result) {
LOGGER.info("Dir created");
}
}
// ZipOutputStream을 FileOutputStream 으로 감쌈
FileOutputStream fout = null;
ZipArchiveOutputStream zout = null;
FileInputStream fin = null;
try {
fout = new FileOutputStream(file);
zout = new ZipArchiveOutputStream(fout);
for (EditorFileVO vo : fileList) {
try {
//본래 파일명 유지
ZipArchiveEntry zipEntry = new ZipArchiveEntry(vo.getOriginFileNm());
zout.putArchiveEntry(zipEntry);
//경로포함 압축
//zout.putNextEntry(new ZipEntry(sourceFiles.get(i)));
java.io.File voFile = new java.io.File(vo.getFullPath());
fin = new FileInputStream(voFile);
byte[] buf = new byte[1024];
int len;
// input file을 1024바이트로 읽음, zip stream에 읽은 바이트를 씀
while((len = fin.read(buf)) > 0) {
zout.write(buf, 0, len);
}
} catch (IOException e) {
LOGGER.error("fail to process zipDown file {}", e);
// throw new Exception(e.getMessage());
} finally {
EgovResourceCloseHelper.close(fin, zout);
}
}
} catch (IOException e) {
LOGGER.error("fail to process zipDown file {}", e);
} finally {
EgovResourceCloseHelper.close(zout);
}
String userAgent = req.getHeader("User-Agent");
String conVstr = null;
if (userAgent.contains("MSIE")) {
conVstr = URLEncoder.encode(zipFileNm,"UTF-8");
} else if (userAgent.contains("Trident")) {
conVstr = URLEncoder.encode(zipFileNm,"UTF-8");
} else if(userAgent.contains("Chrome")) {
conVstr = new String(zipFileNm.getBytes("UTF-8"), "ISO-8859-1");
} else if(userAgent.contains("Opera")) {
conVstr = new String(zipFileNm.getBytes("UTF-8"), "ISO-8859-1");
} else if (userAgent.contains("Mozilla")){
conVstr = new String(zipFileNm.getBytes("UTF-8"), "ISO-8859-1");
} else {
conVstr = new String(zipFileNm.getBytes("UTF-8"), "ISO-8859-1");
}
res.setHeader("Content-Disposition", "attachment; fileName=\"" + conVstr + "\";");
res.setContentType("application/octet-stream;charset=UTF-8");
res.setHeader("Content-Transfer-Encoding", "binary");
FileInputStream fis = null;
BufferedInputStream bis = null;
ServletOutputStream so = null;
BufferedOutputStream bos = null;
try {
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
so = res.getOutputStream();
bos = new BufferedOutputStream(so);
byte[] data = new byte[2048];
int input=0;
while((input=bis.read(data))!=-1){
bos.write(data,0,input);
bos.flush();
}
} catch (IOException e) {
LOGGER.error("fail to process zipDown file {}", e);
} finally {
EgovResourceCloseHelper.close(fis, bis, so, bos);
}
} catch (IOException e) {
LOGGER.error("fail to process zipDown file {}", e);
} finally {
File.deleteDirFileFn(zipFilePath);
}
}
}