您的位置:首页 > 其它

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

2014-08-25 09:56 120 查看
如题,由于工作需要,需要基于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;

}


以上就是文件下载的全部方法,分享给需要的人参考。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: