Web项目中使用java Struts2实现Zip、xml文件的动态创建和下载(Zip文件中动态存在多个xml文件)

web项目中有时候会遇到动态生成zip并下载的需求,但是在生成zip文件的时候我们又不希望产生冗余的临时文件。下面将

介绍我的处理方式。有不妥的地方还希望大家批评指教。


此次需求描述如下:

1.根据数据动态生成XML文件
2.将动态生成的XML文件(一个或多个)整合打包成一个Zip文件
3.客户通过浏览器点击后完成Zip文件的下载

下面开始开发相应功能

1.根据数据动态生成XML文件

这里使用dom4j-1.6.1.jar来实现XML的读取和创建:


public class XmlHandleDom4jHelper{

	/**
	 * Creating a new XML document
	 * 
	 * @author hli
	 */
	public static Document generateDocument() {
		Document document = DocumentHelper.createDocument();
		document.addComment("创建XML");
		Element root = document.addElement("root");
		Element author1 = root.addElement("author").addAttribute("name", "李红").addAttribute("age", "25").addText("李红");
		
		Element author2 = root.addElement("info").addAttribute("QQ", "317962765").addText("317962765");
		
		return document;
	}
	
	
	/**
	 * Writing a document to a file
	 * 
	 * @param document
	 * @throws IOException
	 */
	public static void write(ByteArrayOutputStream byteArrayOutputStream,Document document) throws IOException {
		OutputFormat format = OutputFormat.createPrettyPrint();
		format.setTrimText(true);
		format.setNewLineAfterDeclaration(false);
		XMLWriter writer = new XMLWriter(byteArrayOutputStream, format);
		writer.write(document);
		writer.flush();
		writer.close();
	}
}
	

2.动态生成Zip文件

/**
	 * 生成ZIP文件(不生成临时文件)
	 * 
	 * @param out
	 * @author hli
	 * @return byte[] ZIP文件byte数组
	 */
	public byte[] generateCommonTransZipStreamNoTempFile() {
		
		byte[] zipData = null;
		try {
			
			List xmlFileListByteOutputStream = new ArrayList();
			
			ByteArrayOutputStream xmlFileByteArrayOutputStream = null;
			
			for ( int num = 1 ; num < 3 ; num++ ) {
				
				xmlFileByteArrayOutputStream = new ByteArrayOutputStream();
				
				Document document = XmlHandleDom4jHelper.generateDocument();
				
				XmlHandleDom4jHelper.write(xmlFileByteArrayOutputStream,document);		
			
				
				xmlFileListByteOutputStream.add(xmlFileByteArrayOutputStream);
				
			}
			
			ByteArrayOutputStream outputStreamByte = new ByteArrayOutputStream();
			// ----压缩文件:
			// FileOutputStream f = new FileOutputStream("F:\\report\\abc.zip");
			
			// 使用指定校验和创建输出流
			CheckedOutputStream csum = new CheckedOutputStream(outputStreamByte, new CRC32());
			
			ZipOutputStream zos = new ZipOutputStream(csum);
			zos.setEncoding("GBK");
			
			for ( int i = 0 ; i < xmlFileListByteOutputStream.size() ; i++ ) {
				
				ByteArrayOutputStream byteStream = xmlFileListByteOutputStream.get(i);
				
				byte[] bytes = byteStream.toByteArray();
				
				ByteArrayInputStream byInputStream = new ByteArrayInputStream(bytes);
				
				// 开始写入新的ZIP文件条目并将流定位到条目数据的开始处
				ZipEntry zipEntry = new ZipEntry("Test_xml_file_" + i);
				zos.putNextEntry(zipEntry);
				byte[] buffer = new byte[1024];
				int readCount = byInputStream.read(buffer);
				
				while (readCount != -1) {
					zos.write(buffer, 0, readCount);
					readCount = byInputStream.read(buffer);
				}
				// 注,在使用缓冲流写压缩文件时,一个条件完后一定要刷新一把,不 然可能有的内容就会存入到后面条目中去了
				zos.flush();
				
				// 文件读完后关闭
				byInputStream.close();
				
			}
			zos.closeEntry();// 此处 一定要close,否则下载的ZIP错误
			
			zos.close();
			
			zipData = outputStreamByte.toByteArray();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return zipData;
	}

3.客户通过浏览器点击后完成Zip文件的下载

此处使用Struts2的文件下载功能
备注:参考我另一篇文章: 点击打开链接

A>在action中编码:

public InputStream getDownZipStream() {
		
		byte[] zipData = reportService.generateCommonTransZipStreamNoTempFile();
		
		//此处为下载的文件名称
		//若为中文,则需要进行编码
		downFileName = "downZip.zip";
		
		
		return new ByteArrayInputStream(zipData);
	}

B>Struts2配置文件中:


			
				application/zip
				downZipStream
				attachment;filename="${downFileName}"
				4096
	
	


完成上述编程后,所需需求实现且无临时文件生成。

备注:上传java方法实现需要优化,暂时先记下,待日后完善



你可能感兴趣的:(J2EE)