基于tapestry5.0实现的文件下载

如题,由于工作需要,需要基于tapestry5.0实现数据导出Word,其中有一块需要实现的就是文件下载,网上有很多通过servlet实现的例子,这里分享一个用tapestry实现的例子,供大家参考。

  ps: 笔者仅有一年Java web开发经验,接触tapestry也不到三个月,加上是第一次在网上写此类文章,如果下面写到有错误的地方,请指正。


我们知道,文件的下载都是通过服务器端返回二进制流给客户端的形式实现,用servlet可以直接用Response写好信息后返回给客户端。但是在tapestry框架中不方便通过response对象来实现下载,框架提供了一个专门用于下载的接口 StreamResponse ,通过实现此接口并重写其方法就可以实现文件的下载。话不多说,直接上代码。

/***********************************************************************************
* ClassCode: FileDownload
* ClassName: 文件下载
* Author: Toby_lee
* 
* 
* 模块名称: 文件下载类
* 模块功能: 提供文件下载功能
* Modified: 2014年8月20日09:44:08
*
* 
*  
* 
*
***********************************************************************************/

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.tapestry5.StreamResponse;
import org.apache.tapestry5.services.Response;

/**
 *  Word文件下载

 *  模块名称:文件下载
 *  模块功能: 根据文件主题和文件路径,生成二进制流并返回给客户端
 * 
 * @author Toby_lee
 */
public class FileDownload implements StreamResponse {

	/**
	 *  下载文件路径
	 */
	private String filePath = null;

	/**
	 *  下载文件主题
	 */
	private String fileName = null;

	/**
	 *  构造方法
	 *  
	 * @param fileName 生成文件名主题
	 * @oaran filePath 下载文件路径
	 */
	public FileDownload(String fileName, String filePath) {

		this.fileName = fileName;
		this.filePath = filePath;
	}

	/**
	 * 无参构造
	 */
	public FileDownload() {

	}

	/**
	 *  获取返回流
	 */
	public InputStream getStream() throws IOException {

		// 待下载文件
		File downFile = new File(filePath);

		ByteArrayOutputStream baos = null;
		if (filePath != null && downFile.exists()) {

			// 生成返回的文件流
			FileInputStream fis = new FileInputStream(filePath);

			BufferedInputStream bis = new BufferedInputStream(fis);

			baos = new ByteArrayOutputStream();

			byte[] buf = new byte[1024];

			// 读取bis流
			int byt = bis.read(buf, 0, 1024);

			while(byt != -1){
				baos.write(buf, 0, byt);
				byt = bis.read(buf, 0, 1024);
			}

			bis.close();

			// 删除临时文件
			downFile.delete();
		}

		return new ByteArrayInputStream(baos.toByteArray());
	}

	/**
	 *  设置返回流的 ContentType
	 */
	public String getContentType() {

		return "application/x-zip-compressed";
	}

	/**
	 * 返回流相关设置 
	 */
	public void prepareResponse(Response response) {
		try {
			response.setHeader("content-disposition", "attachment; filename="
					+ new String((fileName + ".zip").getBytes(), "ISO-8859-1"));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * @return the fileName
	 */
	public String getFilePath() {
		return filePath;
	}

	/**
	 * @param fileName the fileName to set
	 */
	public void setFilePath(String fileName) {
		this.filePath = fileName;
	}

	/**
	 * @return the fileName
	 */
	public String getFileName() {
		return fileName;
	}

	/**
	 * @param fileName the fileName to set
	 */
	public void setFileName(String fileName) {
		this.fileName = fileName;
	}

	
}

各个方法说明:   

FileDownload():  有参的构造方法,用于在创建对象时传入待下载的文件和下载的默认名称。

getContentType():这个方法和servlet下载时设置的contenttype一样,设置返回文件的类型。 代码里返回的是zip文件类型。

prepareResponse():此方法用于设置一些头文件信息,默认文件名称就是在这里设置。代码中设置的是  fileName + ".zip"

getStream():此方法是实现下载的主要方法,这个方法返回一个InputStream 对象,用于返回给客户端。此处多做一些解释:一般文件的下载的思路是通过客户端请求,到数据库中查询数据整理后,在服务器上生成临时文件,然后将临时文件读进二进制流,然后返回给客户端,待完全返回给客户端后删除文件.。但是此处需要将文件完全读进二进制流,然后返回给客户端,不好选择文件删除的时间,有试过在客户端通过Ajax来实现文件删除,但是判断文件是否已经下载完成也是一个难题。参考系统中其他实现下载的方法,均是直接通过数据生成二进制流,返回给客户端,没有生成文件,也就不需要删除。而此处必须要生成临时文件,然后笔者的想法是将临时文件读进一个缓冲区,然后删除文件,再将文缓冲区的数据返回给客户端。最后通过BufferedInputStream 和ByteArrayOutputStream 两个类实现了这个想法。解决了删除临时文件的问题。


最后来讲讲如何使用这个文件下载类

  其实使用这个类很简单了,只需要在响应actionlink事件的方法中创建文件下载类的对象,然后返回该对象即可

	/**
	 *  文件下载
	 */
	public Object onActionFromFileDownload() { 

    		FileDownload fileDownload = new FileDownload("学员信息", stdtInfoFile);

		return fileDownload;

}


   以上就是文件下载的全部方法,分享给需要的人参考。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值