Browse Source

压缩解压缩过程中zip文件不写入本地

sunyj 9 years ago
parent
commit
1da9216d71

+ 13 - 30
src/main/java/com/uas/report/controller/FileController.java

@@ -1,7 +1,5 @@
 package com.uas.report.controller;
 
-import java.io.IOException;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -16,9 +14,8 @@ import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.multipart.MultipartFile;
 
-import com.uas.report.core.exception.ReportException;
 import com.uas.report.service.FileService;
-import com.uas.report.support.SysConf;
+import com.uas.report.util.ZipUtils;
 
 /**
  * 文件操作请求
@@ -33,9 +30,6 @@ public class FileController {
 	@Autowired
 	private FileService fileService;
 
-	@Autowired
-	private SysConf sysConf;
-
 	@RequestMapping("/autoDeploy")
 	@ResponseBody
 	public String autoDeploy(String userNames) {
@@ -78,14 +72,7 @@ public class FileController {
 	 */
 	@RequestMapping("/download/zip")
 	public void downloadZip(String userName, HttpServletResponse response) {
-		if (StringUtils.isEmpty(userName)) {
-			throw new ReportException("未传入当前账套用户名!");
-		}
-		String zipFilePath = fileService.getZip(userName);
-		if (zipFilePath.isEmpty()) {
-			throw new ReportException("压缩失败");
-		}
-		fileService.download(zipFilePath, true, response);
+		fileService.downloadZip(userName, response);
 	}
 
 	/**
@@ -110,21 +97,8 @@ public class FileController {
 	 */
 	@RequestMapping("/standardJrxmls")
 	@ResponseBody
-	public Map<String, Object> standardJrxmls(String onlyData, HttpServletResponse response) {
-		// 只返回字节数据,否则下载标准模板zip
-		if (!StringUtils.isEmpty(onlyData) && (onlyData.equals("1") || onlyData.equals("true"))) {
-			Map<String, Object> result = new HashMap<>();
-			// 不直接返回byte[],是因为客户端请求数据时,该请求可能会抛出异常,
-			// 之后客户端获取byte[]数据,进行处理时难以判断数据是文件数据还是异常信息
-			result.put("data", fileService.getStandardJrxmls());
-			return result;
-		}
-		try {
-			response.sendRedirect("download/zip?userName=" + sysConf.getStandardMaster());
-			return null;
-		} catch (IOException e) {
-			throw new ReportException(e).setDetailedMessage(e);
-		}
+	public void standardJrxmls(String onlyData, HttpServletResponse response) {
+		fileService.downloadStandardJrxmls(response);
 	}
 
 	@RequestMapping("/delete")
@@ -139,4 +113,13 @@ public class FileController {
 		return fileService.listFiles(filePath, isAbsolutePath);
 	}
 
+	@RequestMapping("/test")
+	@ResponseBody
+	public String test() {
+		byte[] data = ZipUtils.zipFolder("C:/sunyj/reports/60/tmp", null);
+		if (!ArrayUtils.isEmpty(data)) {
+			ZipUtils.unzip(data, "C:/sunyj/reports/tmp");
+		}
+		return "od";
+	}
 }

+ 14 - 5
src/main/java/com/uas/report/service/FileService.java

@@ -72,19 +72,17 @@ public interface FileService {
 
 	/**
 	 * 获取标准模板
-	 * 
-	 * @return 标准模板数据
 	 */
-	public byte[] getStandardJrxmls();
+	public void downloadStandardJrxmls(HttpServletResponse response);
 
 	/**
 	 * 获取账套下的所有资源
 	 * 
 	 * @param userName
 	 *            账套名称
-	 * @return 账套下所有资源的压缩包路径
+	 * @param response
 	 */
-	public String getZip(String userName);
+	public void downloadZip(String userName, HttpServletResponse response);
 
 	/**
 	 * 下载文件
@@ -97,6 +95,17 @@ public interface FileService {
 	 */
 	public void download(String filePath, Boolean isAbsolutePath, HttpServletResponse response);
 
+	/**
+	 * 下载文件
+	 * 
+	 * @param data
+	 *            文件数据
+	 * @param fileName
+	 *            文件名称
+	 * @param response
+	 */
+	public void download(byte[] data, String fileName, HttpServletResponse response);
+
 	/**
 	 * 递归删除文件(夹)
 	 * 

+ 62 - 59
src/main/java/com/uas/report/service/impl/FileServiceImpl.java

@@ -51,7 +51,7 @@ public class FileServiceImpl implements FileService {
 	/**
 	 * 查看、压缩文件时,对文件进行过滤
 	 */
-	private FileFilter fileFilter = new FileFilter() {
+	public static final FileFilter fileFilter = new FileFilter() {
 		@Override
 		public boolean accept(File file) {
 			if (file == null || !file.exists()) {
@@ -74,6 +74,7 @@ public class FileServiceImpl implements FileService {
 			throw new ReportException("参数不能为空:userNames");
 		}
 		try {
+			logger.info("get standardJrxmls from " + sysConf.getStandardJrxmlsUrl() + "...");
 			// 获取标准模板数据
 			JSONObject jsonObject = JSONObject.parseObject(IOUtils.toString(HttpClients.createDefault()
 					.execute(new HttpGet(URI.create(sysConf.getStandardJrxmlsUrl()))).getEntity().getContent()));
@@ -81,14 +82,10 @@ public class FileServiceImpl implements FileService {
 			if (ArrayUtils.isEmpty(data)) {
 				throw new ReportException("标准模板不存在");
 			}
-			// 写入本地zip文件
-			String filePath = new StringBuilder(sysConf.getLocalBaseDir()).append("/")
-					.append(sysConf.getStandardMaster()).append(".zip").toString();
-			FileUtils.create(filePath, data);
 			String[] userNameArray = userNames.split(",");
 			// 创建账套路径并解压模板zip包
 			for (String userName : userNameArray) {
-				ZipUtils.unzip(filePath, sysConf.getLocalBaseDir() + "/" + userName);
+				ZipUtils.unzip(data, getMasterPath(userName));
 			}
 			return "已自动部署:" + userNames;
 		} catch (UnsupportedOperationException | IOException e) {
@@ -97,7 +94,7 @@ public class FileServiceImpl implements FileService {
 	}
 
 	@Override
-	public String upload(final String userName, String fileType, MultipartFile file) {
+	public String upload(final String userName, String fileType, final MultipartFile file) {
 		String message = "";
 		if (StringUtils.isEmpty(userName)) {
 			message = "未传入当前账套用户名!";
@@ -113,6 +110,23 @@ public class FileServiceImpl implements FileService {
 			fileType = "jrxml";
 		}
 
+		// 如果上传的是模板zip包,直接获取字节数据,将其解压到相应的账套下
+		if (fileType.equals("zip")) {
+			message = "文件上传成功";
+			logger.info(message);
+			new Thread(new Runnable() {
+				@Override
+				public void run() {
+					try {
+						ZipUtils.unzip(file.getBytes(), getMasterPath(userName));
+					} catch (IOException e) {
+						throw new ReportException("文件解压失败").setDetailedMessage(e);
+					}
+				}
+			}).start();
+			return message;
+		}
+
 		String fileName = file.getOriginalFilename();
 		StringBuilder stringBuilder = new StringBuilder(sysConf.getLocalBaseDir()).append("/");
 		// jrxml模板和图片分别放在jrxml和Picture文件夹下,其他资源放在当前账套根路径下
@@ -122,6 +136,8 @@ public class FileServiceImpl implements FileService {
 			stringBuilder.append(userName).append("/").append("Picture").append("/");
 		} else if (fileType.equals("other")) {
 			stringBuilder.append(userName).append("/");
+		} else {
+			throw new ReportException("不支持上传该类型的文件:" + fileType);
 		}
 
 		stringBuilder.append(fileName);
@@ -134,20 +150,10 @@ public class FileServiceImpl implements FileService {
 			file.transferTo(targetFile);
 			message = "成功上传文件至:" + targetFile.getPath();
 			logger.info(message);
-			// 如果上传的是模板zip包,将其解压到相应的账套下
-			if (fileType.equals("zip")) {
-				new Thread(new Runnable() {
-					@Override
-					public void run() {
-						ZipUtils.unzip(targetFile.getPath(),
-								new File(targetFile.getPath()).getParent() + File.separator + userName);
-					}
-				}).start();
-			}
 			return message;
 		} catch (IllegalStateException | IOException e) {
 			e.printStackTrace();
-			message = "上传文件失败: " + fileName;
+			message = "文件上传失败: " + fileName;
 			logger.error(message);
 			return message;
 		}
@@ -180,7 +186,6 @@ public class FileServiceImpl implements FileService {
 		}
 		logger.info(message);
 		return message;
-
 	}
 
 	@Override
@@ -199,38 +204,21 @@ public class FileServiceImpl implements FileService {
 	}
 
 	@Override
-	public byte[] getStandardJrxmls() {
-		// 压缩标准模板
-		String zipFilePath = getZip(sysConf.getStandardMaster());
-		if (zipFilePath.isEmpty()) {
-			throw new ReportException("压缩失败");
-		}
-		File zipFile = new File(zipFilePath);
-		if (!zipFile.exists()) {
-			throw new ReportException("文件不存在:" + zipFilePath);
-		}
-		if (!zipFile.isFile()) {
-			throw new ReportException("并非文件:" + zipFilePath);
-		}
-		try {
-			InputStream inputStream = new FileInputStream(zipFile);
-			byte[] data = new byte[inputStream.available()];
-			inputStream.read(data);
-			inputStream.close();
-			return data;
-		} catch (IOException e) {
-			throw new ReportException(e).setDetailedMessage(e);
-		}
+	public void downloadStandardJrxmls(HttpServletResponse response) {
+		downloadZip(sysConf.getStandardMaster(), response);
 	}
 
 	@Override
-	public String getZip(String userName) {
-		// 账套路径
-		String folderPath = getMasterPath(userName);
-		// 压缩后的压缩包路径,与账套在同一级
-		String zipFilePath = folderPath + ".zip";
-		ZipUtils.zipFolder(folderPath, zipFilePath, fileFilter);
-		return zipFilePath;
+	public void downloadZip(String userName, HttpServletResponse response) {
+		if (StringUtils.isEmpty(userName)) {
+			throw new ReportException("未传入当前账套用户名!");
+		}
+		String masterPath = getMasterPath(userName);
+		byte[] data = ZipUtils.zipFolder(masterPath, FileServiceImpl.fileFilter);
+		if (ArrayUtils.isEmpty(data)) {
+			throw new ReportException("压缩失败");
+		}
+		download(data, new File(masterPath).getName() + ".zip", response);
 	}
 
 	@Override
@@ -244,25 +232,40 @@ public class FileServiceImpl implements FileService {
 		if (!file.exists()) {
 			throw new ReportException("文件不存在:" + filePath);
 		}
+
+		byte[] data = null;
+		String fileName = "";
 		// 下载文件夹之前,需进行压缩
 		if (file.isDirectory()) {
-			String zipFilePath = getZip(getRelativePath(file));
-			if (zipFilePath.isEmpty()) {
-				throw new ReportException("压缩失败");
+			fileName = file.getName() + ".zip";
+			data = ZipUtils.zipFolder(filePath, fileFilter);
+		} else {
+			fileName = file.getName();
+			try {
+				InputStream inputStream = new FileInputStream(file);
+				data = new byte[inputStream.available()];
+				inputStream.read(data);
+				inputStream.close();
+			} catch (IOException e) {
+				e.printStackTrace();
 			}
-			download(zipFilePath, true, response);
-			return;
+		}
+		if (ArrayUtils.isEmpty(data)) {
+			throw new ReportException("下载失败:" + filePath);
+		}
+		download(data, fileName, response);
+	}
+
+	@Override
+	public void download(byte[] data, String fileName, HttpServletResponse response) {
+		if (ArrayUtils.isEmpty(data) || StringUtils.isEmpty(fileName) || response == null) {
+			throw new ReportException("参数不能为空:data,filePath,response");
 		}
 		try {
-			InputStream inputStream = new FileInputStream(file);
-			byte[] data = new byte[inputStream.available()];
-			inputStream.read(data);
-			response.setHeader("Content-Disposition",
-					"attachment;filename=" + URLEncoder.encode(file.getName(), "UTF-8"));
+			response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
 			OutputStream outputStream = response.getOutputStream();
 			outputStream.write(data);
 			outputStream.flush();
-			inputStream.close();
 			outputStream.close();
 		} catch (IOException e) {
 			e.printStackTrace();

+ 80 - 0
src/main/java/com/uas/report/util/ZipUtils.java

@@ -1,5 +1,7 @@
 package com.uas.report.util;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileFilter;
 import java.io.FileInputStream;
@@ -10,6 +12,7 @@ import java.io.OutputStream;
 import java.util.Enumeration;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
+import java.util.zip.ZipInputStream;
 import java.util.zip.ZipOutputStream;
 
 import org.apache.log4j.Logger;
@@ -27,6 +30,43 @@ public class ZipUtils {
 
 	private static final Logger logger = Logger.getLogger(ZipUtils.class);
 
+	/**
+	 * 压缩文件夹
+	 * 
+	 * @param sourceFolderPath
+	 *            将压缩的文件夹
+	 * @param fileFilter
+	 *            文件过滤器,不压缩某些文件
+	 * @return 压缩后的数据
+	 */
+	public static byte[] zipFolder(String sourceFolderPath, FileFilter fileFilter) {
+		if (StringUtils.isEmpty(sourceFolderPath)) {
+			return null;
+		}
+		File folder = new File(sourceFolderPath);
+		if (!folder.exists() || !folder.isDirectory()) {
+			throw new ReportException("路径不存在或并非文件夹:" + sourceFolderPath);
+		}
+		File[] files = folder.listFiles();
+		if (files.length < 0) {
+			throw new ReportException("空文件夹:" + sourceFolderPath);
+		}
+
+		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+		byte[] zipData = null;
+		try {
+			ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
+			putNextEntryFromFolder(zipOutputStream, folder, "", fileFilter);
+			zipOutputStream.close();
+			logger.info("Zip done");
+			zipData = outputStream.toByteArray();
+			outputStream.close();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		return zipData;
+	}
+
 	/**
 	 * 压缩文件夹
 	 * 
@@ -99,6 +139,46 @@ public class ZipUtils {
 		}
 	}
 
+	/**
+	 * 解压缩
+	 * 
+	 * @param zipData
+	 *            压缩包数据
+	 * @param folderPath
+	 *            解压缩后的文件路径
+	 */
+	public static void unzip(byte[] zipData, String folderPath) {
+		if (StringUtils.isEmpty(folderPath)) {
+			return;
+		}
+
+		try {
+			ZipInputStream zipInputStream = new ZipInputStream(new ByteArrayInputStream(zipData));
+			ZipEntry zipEntry;
+			while ((zipEntry = zipInputStream.getNextEntry()) != null) {
+				if (zipEntry.isDirectory()) {
+					continue;
+				}
+				File outFile = new File(folderPath + File.separator + zipEntry.getName());
+				if (!outFile.getParentFile().exists()) {
+					outFile.getParentFile().mkdirs();
+				}
+
+				OutputStream outputStream = new FileOutputStream(outFile);
+				int b;
+				while ((b = zipInputStream.read()) != -1) {
+					outputStream.write(b);
+				}
+				outputStream.close();
+				logger.info("Unziped to... " + outFile.getPath());
+			}
+			zipInputStream.close();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		logger.info("Unzip done");
+	}
+
 	/**
 	 * 解压缩
 	 * 

+ 0 - 1
src/main/webapp/WEB-INF/views/console.html

@@ -70,7 +70,6 @@
 				<strong><li class="title1">标准模板</li></strong>
 				<ol>
 					<li><a target="_blank">file/standardJrxmls</a></li>
-					<li><a target="_blank">file/standardJrxmls?onlyData=1</a></li>
 				</ol>
 				<strong><li class="title1">自动部署新账套</li></strong>
 				<ol>