和传统的JSP一样,在flex中,有的时候也需要实现文件上传和下载的功能,但是在flex里文件的上传和下载的实现相对来说比较复杂,如何实现,请看下面。
??? 由于flex是一个比较新的技术,在研究的时候,还是按着JSP的方式去尝试,在开始之初,主要有以下几种思路:
????A、利用ftp的方式进行文件的上传和下载,需要利用flex的socket接口。
????B、利用webService的方式来进行文件的上传和下载
????C、利用flex+sevlet+fileupload组件实现文件的上传和下载
??? 在通过比较后,最后选择了第三种,用Flex+sevlet的方式来完成文件上传和下载的功能,理由如下(与上面的思路相对应):
????A、涉及到了流的操作,实现起来比较复杂,出现错误的几率比较高
????B、关于flex端的可参考的资料比较少,并且还需要启动webservice服务
????C、这个技术比较成熟,从flex2.0开始,在flex端已经可以引用FileReference类了,并且在java端有成熟的组件可以使用,所以最后考虑使用该种方法来处理。
一、文件的上传
????1、Flex端
????????A、使用到的类介绍:
????????????FileReference 类提供了在用户计算机和服务器之间上载和下载文件的方法。 操作系统对话框会提示用户选择要上载的文件或用于下载的位置。它主要能实现一个文件的上传。
????????????FileReferenceList 类提供了让用户选择一个或多个要上载的文件的方法。 FileReferenceList 对象将用户磁盘上的一组本地文件(一个或多个文件)表示为 FileReference 对象的数组。
????????B、使用 FileReferenceList 类 实现多文件上传:
????????????1) 将该类实例化:var myFileRef = new FileReferenceList();?
????????????2) 调用 FileReferenceList.browse() 方法,该方法将打开一个对话框,让用户选择一个或多个要上载的文件:myFileRef.browse();?
????????????3) 在成功调用 browse() 方法之后,使用 FileReference 对象数组来填充 FileReferenceList 对象的 fileList 属性。?
????????????????对 fileList 数组中的每个元素调用 FileReference.upload()
????????代码如下:


????
/**?*/
/**

?????*?执行上传操作

?????*?*/
????

????
private
?function?upLoadFiles():
void


????

{

????????try


????????
{

????????????selectFileList.browse(new?Array(imageFilter,?textFilter));

????????????selectFileList.addEventListener(Event.SELECT,?selectHandler1);

????????}

????????catch?(error:Error)?


????????
{

????????????Alert.show("文件选择出现错误,请选择正确的文件");

????????}

????}


????
/**?*/
/**

?????*?如果文件被选中,则执行该方法

?????*?*/

????function?selectHandler1(event:Event):
void


????

{

????????var?request:URLRequest?=?new?URLRequest("FileUploadServlet");

????????var?upLoadFile:FileReference;?

????????var?upLoadFileList:FileReferenceList?=?FileReferenceList(event.target);

????????var?selectedFileArray:Array?=?upLoadFileList.fileList;

????????login?=(testPress)(PopUpManager.createPopUp(?this,?testPress?,?true));

????????for?(var?i:uint?=?0;?i?<?selectedFileArray.length;?i++)


????????
{?

????????????upLoadFile?=?FileReference(selectedFileArray[i]);

????????????upLoadFile.addEventListener(Event.COMPLETE,?UpLoadcompleteHandler);

????????????upLoadFile.addEventListener(ProgressEvent.PROGRESS,?progressHandler);?

????????????try


????????????
{

????????????????upLoadFile.upload(request);

????????????}

????????????catch?(error:Error)


????????????
{

????????????????Alert.show(error.message.toString());

????????????}

????????}

????}

????function?UpLoadcompleteHandler(event:Event):
void


????

{

?????????var?upLoadFiles:FileReference?=?FileReference(event.target);

?????????var?fileNames?=?upLoadFiles.name;

?????????//Alert.show('文件'+fileNames+'上传成功')

?????????login.myLabels.text?=?'文件'+fileNames+'上传成功';

????}

?????
private
?function?progressHandler(e:ProgressEvent):
void


??

{?

????var?proc:?uint?=?e.bytesLoaded?/?e.bytesTotal?*?100;??

????login.bar.setProgress(proc,?100);??

????login.bar.label=?"当前进度:?"?+?"?"?+?proc?+?"%";??

?}
?
testPress.mxml

<?
xml?version="1.0"?encoding="utf-8"
?>

<
mx:TitleWindow?
xmlns:mx
="http://www.adobe.com/2006/mxml"
?layout
="absolute"
?width
="528"
?height
="236"
>

<
mx:Script
>

????
<
????????import?mx.managers.PopUpManager;

????????public?function?clickMe():void?{

????????????PopUpManager.removePopUp(this);

????????}

????
]]>

</
mx:Script
>

????
<
mx:ProgressBar?
id
="bar"
?labelPlacement
="bottom"
?themeColor
="#F20D7A"
??

minimum
="0"
?visible
="true"
?maximum
="100"
?label
="当前进度:?0%"
??

direction
="right"
?mode
="manual"
?width
="200"
?x
="154"
?y
="84"
/>
??

????
<
mx:Button?
x
="221"
?y
="135"
?label
="关闭"
?click?
=?"clickMe();"
/>

????
<
mx:Label?
x
="173"
?y
="27"
?id
="myLabels"
?width
="157"
/>


</
mx:TitleWindow
>

????2、JAVA端
?????接受Flex端的请求,在JAVA端利用apache的fileupload类库实现上传功能。代码如下:

import
?java.io.File;

import
?java.io.FileInputStream;

import
?java.io.IOException;

import
?java.io.InputStream;

import
?java.util.Iterator;

import
?java.util.List;

import
?java.util.Properties;


import
?javax.servlet.ServletContext;

import
?javax.servlet.ServletException;

import
?javax.servlet.http.HttpServlet;

import
?javax.servlet.http.HttpServletRequest;

import
?javax.servlet.http.HttpServletResponse;


import
?org.apache.commons.fileupload.FileItem;

import
?org.apache.commons.fileupload.FileUploadException;

import
?org.apache.commons.fileupload.disk.DiskFileItemFactory;

import
?org.apache.commons.fileupload.servlet.ServletFileUpload;


public
?
class
?FileUploadServlet?
extends
?HttpServlet



{


????//?private?String?uploadPath?=?"D:upload";

????private?String?path?=?"file_path.properties";

????private?String?skStr?=?"";

????private?String?uploadPath?=?"";

????private?int?maxPostSize?=?1000?*?1024?*?1024;


????public?void?doPost(HttpServletRequest?req,?HttpServletResponse?res)?throws?ServletException,

????????????IOException


????
{

????????String?filePathaa?=?this.getServletConfig().getServletContext().getRealPath("/");


????????Properties?p?=?loadProperties(path);


????????uploadPath?=?p.getProperty("filepath");


????????res.setContentType("text/html;charset=UTF-8");

????????req.setCharacterEncoding("UTF-8");


????????DiskFileItemFactory?factory?=?new?DiskFileItemFactory();

????????factory.setSizeThreshold(1024*20);


????????ServletFileUpload?upload?=?new?ServletFileUpload(factory);

????????upload.setSizeMax(maxPostSize);

????????try


????????
{

????????????List?fileItems?=?upload.parseRequest(req);

????????????Iterator?iter?=?fileItems.iterator();

????????????while?(iter.hasNext())


????????????
{

????????????????FileItem?item?=?(FileItem)?iter.next();

????????????????if?(!item.isFormField())


????????????????
{

????????????????????String?name?=?item.getName();


????????????????????try


????????????????????
{

????????????????????????File?skFile?=?new?File(uploadPath?+?name);

????????????????????????if?(skFile.exists())


????????????????????????
{

????????????????????????????skFile.delete();

????????????????????????????item.write(new?File(uploadPath?+?name));


????????????????????????}

????????????????????????else


????????????????????????
{

????????????????????????????item.write(new?File(uploadPath?+?name));

????????????????????????}


????????????????????}?catch?(Exception?e)


????????????????????
{

????????????????????????e.printStackTrace();

????????????????????}

????????????????}

????????????}

????????}?catch?(FileUploadException?e)


????????
{

????????????e.printStackTrace();

????????}


????}


????public?Properties?loadProperties(String?path)?throws?IOException


????
{


????????InputStream?in?=?this.getClass().getResourceAsStream(path);

????????//


????????Properties?p?=?new?Properties();


????????p.load(in);

????????in.close();

????????return?p;

????}


}
还要修正web.xml,添加如下内容

<!--
?For?file?uploaded?
-->

???
<
servlet
>

????????
<
servlet-name
>
FileUploadServlet
</
servlet-name
>

????????
<
servlet-class
>
FileUploadServlet
</
servlet-class
>

????
</
servlet
>


????
<
servlet-mapping
>

????????
<
servlet-name
>
FileUploadServlet
</
servlet-name
>

????????
<
url-pattern
>
/FileUploadServlet
</
url-pattern
>

????
</
servlet-mapping
>
二、文件的下载
????
????调用的方法:private function downLoadFiles(urlAdd:String):void
????参数urlAdd就是用户的ip地址,如果使用本地的localhost就会产生安全沙箱问题,因此让用户自己输入自己的ip地址。这样就避免了安全沙箱的问题。如果是本机启动服务,访问地址,需要输入IP,不能用localhost来代替本机的IP地址,否则,还是会出现安全沙箱问题。
?????FileReference.download() 方法提示用户提供文件的保存位置并开始从远程 URL 进行下载。直接加载请求路径下载,不需要后台的支持。代码如下:

import
?com.systex.flex.util.testPress;


import
?flash.net.FileReferenceList;


import
?mx.controls.Alert;

import
?mx.managers.PopUpManager;

????var?imageFilter:FileFilter?
=
?
new
?FileFilter(
"
Image?Files?(*.jpg,?*.jpeg,?*.gif,?*.png)
"
,?
"
*.jpg;?*.jpeg;?*.gif;?*.png
"
);

????var?textFilter:FileFilter?
=
?
new
?FileFilter(
"
Text?Files?(*.txt,?*.rtf,?*.zip)
"
,?
"
*.txt;?*.rtf;?*.zip
"
);

????var?selectFileList:FileReferenceList?
=
?
new
?FileReferenceList();

????var?selectedFileArray:Array?
=
?
new
?Array();

????var?login:testPress?
=
?
new
?testPress();

????var?downloadURL:URLRequest;

????var?DownLoadfile:FileReference;?
//
这是要主要的地方

????
//
http://
XX.XX.XX.XX:8080/upload/main.zip

????
private
?function?downLoadFiles(urlAdd:String):
void


????

{

????????downloadURL?=?new?URLRequest(urlAdd);

????????DownLoadfile?=?new?FileReference();

????????configureListeners(DownLoadfile);

????????DownLoadfile.download(downloadURL);

????}


?????
private
?function?configureListeners(dispatcher:IEventDispatcher):
void
?

{

????????dispatcher.addEventListener(Event.COMPLETE,?completeHandler);


????}

????


????
private
?function?completeHandler(event:Event):
void
?

{

????mx.controls.Alert.show("文件下载成功");

????}
这里的是上面上传代码的上部分
附上测试的MXML

<?
xml?version="1.0"?encoding="utf-8"
?>

<
mx:Application?
xmlns:mx
="http://www.adobe.com/2006/mxml"
?layout
="absolute"

????
>

<
mx:Script?
source
="UpDownLoadFiles.as"
/>


????
<
mx:Canvas?
width
="100%"
?height
="100%"
?x
="10"
?y
="170"
?fontSize
="15"
>

????
<
mx:VBox?
width
="100%"
?horizontalAlign
="center"
>

????
<
mx:TextInput?
id
="mytextInput"
/>

????
<
mx:Button?
label
="文件下载"
?click
="downLoadFiles('http://'+mytextInput.text+':8080/downLoading/2MSN.rar');"
/>

????
<
mx:Button?
label
="上传文件"
?click
="upLoadFiles();"
/>

????
</
mx:VBox
>

????
</
mx:Canvas
>

</
mx:Application
>
fileupload下载地址