前阵子由于工作的需要,在项目里写了一个用Flex+Struts2实现的文件下载功能。现在有空整理下~
一.首先是Flex部分的代码(解释下:在点击“下载”按钮后就可以进行下载)
protected function button1_clickHandler(event:MouseEvent):void
{
var p:URLVariables = new URLVariables();
p.fileName = list2.selectedItem;
if(p.fileName==undefined){
Alert.show("请选择要下载的文件!", "提示");
}else{
var filename = p.fileName;
p.path = path;
var request:URLRequest;
var file:FileReference;
request = new URLRequest(HTTPUtilConfig.HTTP_URL+"/CognosRF/download1_down"+HTTPUtilConfig.HTTP_URL_SUFFIX);
request.data = p;
file = new FileReference();
configureListeners(file);
file.download(request,filename);
}
}
private function configureListeners(dispatcher:IEventDispatcher):void{
dispatcher.addEventListener(Event.COMPLETE, completeHandler);
dispatcher.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
}
private function completeHandler(event:Event):void{
Alert.show("文件下载成功!", "提示");
}
private function ioErrorHandler(event:IOErrorEvent):void{
Alert.show("文件下载失败!\n" + event.toString(), "提示");
}
1.在Flex中,文件的上传下载都是依靠flash.net.FileReference类实现的。FileReference类提供了在用户计算机和服务器之间上传和下载文件的方法。利用该类的方法,可以在上传下载前打开操作系统对话框,提示用户选择要上传的文件或用于下载的位置。而后通过HTTP协议上传下载文件。
2.FileReference.download()
下载指定的文件。该方法支持下载任何格式的文件。但是在Flash Player中可以下载文件最大为100M。该方法包含两个参数:服务器端脚本URL和默认的文件名。默认文件名为空时,下载后仍采用文件原来的文件名。(最好还是把文件名参数加上,我当时没加就出错了,下载后的名字不对)
3.在打开对话框,上传下载文件中都可以触发相应的事件。常用的事件如下所示:
❑cancel:当上传或者下载被取消时触发该事件。该事件类型为:flash.events.Event.CANCEL。
❑complete:当下载结束,即Flash Player接收到HTTP状态码200时触发该事件。
该事件的类型为flash.events.Event.COMPLETE。
❑ioError:当上传或下载失败时触发该事件。该事件的型为:flash.events.IOErrorEvent.IO_ERROR。
❑open:当打开选择文件对话框是时触发该事件。该事件的类型为:flash.events.Event.OPEN。
❑progress:上传或者下载的过程中触发该事件。该事件通常与进度条控件(ProgressBar Control)结合
在一起显示当前的上传或者下载的进度。该事件的类型为:flash.events.ProgressEvent.PROGRESS。
❑select:当选中要上传或者下载的时候触发该事件。该事件的类型为flash.events.Event.SELECT。
❑uploadCompleteData:该事件与Complete不同,上传时,服务端接受完数据返回成功消息时,才能触发该事件。
该事件的类型为flash.events.DataEvent.UPLOAD_COMPLETE_DATA。
在上述上传下载的事件发生时,需要使用addEventListener()方法为事件添加事件侦听器。
4.注意FileReference只能上传下载一个文件,如果要以此上传下载多个文件可以使用FileReferenceList类。
调用FileReferenceList.browse()选中多个文件时,创建了一个FileReference对象数组。
该类的属性、方法和事件和FileReference类基本一致,这里不再详述。
二.java+struts2部分
先看java代码
public class DownloadAction extends BaseAction{
private String fileName;
private String path;
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getFileName() {
return fileName;
}
public void setPath(String path) {
this.path = path;
}
//返回一个输入流,作为一个客户端来说是一个输入流,但对于服务器端是一个 输出流
public InputStream getInputStream() {
try {
return new FileInputStream(path+"\\"+fileName);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
public String down(){
return "success";
}
}
Struts2部分——在struts.xml文件中配置相关信息
<package name="CognosRF" namespace="CognosRF" extends="struts">
<action name="*_*" class="{1}" method="{2}">
<result name="success" type="stream" >
<param name="contentType">application/octet-stream</param>
<param name="inputName">inputStream</param>
<param name="contentDisposition">attachment;filename="${fileName}"</param>
<param name="bufferSize">4096</param>
</result>
</action>
</package>
1.
结果类型必须要写成 type="stream" ,与之对应的处理类是 org.apache.struts2.dispatcher.StreamResult。
2.
<param name="inputName">inputStream</param>
中的inputStream对应的是java的DownloadAction类里的public InputStream getInputStream()。
3.
1) <param name="contentDisposition">attachment;fileName="${fileName}"</param>;
contentDisposition
文件下载的处理方式,包括内联(inline)和附件(attachment)两种方式,而附件方式会弹出文件保存对话框,否则浏览器会尝试直接显示文件。
2) attachment :下载时会打开下载框;
3) fileName="${fileName}" :在这定义的名字是一个动态的,该名字是显示在下载框上的文件名字。