目的:文件上传组件测试,Flex通过BlazeDS与后台Java代码完成文件上传。
步骤:
1.定义文件上传的结果事件FileUploadEvent,它作为封装文件上传的结果信息的类。
//FileUploadEvent.as
package org.xjh.events{
import flash.events.Event;
import mx.rpc.Fault;
/**
* 功能:文件上传结果事件
*/
public class FileUploadEvent extends Event{
//结果信息
public static const RESULT:String = "result";
public static const FAULT:String = "fault";
//结果信息对象,可以拿到服务端上传文件操作的返回结果
private var _result:Object;
private var _fault:Fault;
public function FileUploadEvent(type:String, result:Object=null, fault:Fault=null)
{
super(type, true);
this._result = result;
this._fault = fault;
}
//result 的getter与setter
public function get result():Object{
return _result;
}
public function set result(value:Object):void{
_result = value;
}
//fault 的getter与setter
public function get fault():Fault{
return _fault;
}
public function set fault(value:Fault):void{
_fault = value;
}
}
}
2. 定义文件上传核心组件XjhFileUploader,由它实际完成文件上传操作。
//XjhFileUploader.mxml
<?xml version="1.0" encoding="utf-8"?>
<!--
功能:文件上传组件
-->
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="init()"
width="250" height="40">
<s:layout>
<s:BasicLayout/>
</s:layout>
<fx:Declarations>
<s:RemoteObject id="fileUpDownloadRemoteObj" destination="fileUpDownloadService" result="upload_resultHandler(event)"
fault="upload_faultHandler(event)"/>
</fx:Declarations>
<fx:Metadata>
[Event(name="result", type="org.xjh.events.FileUploadEvent")]
[Event(name="fault", type="org.xjh.events.FileUploadEvent")]
</fx:Metadata>
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.messaging.channels.StreamingAMFChannel;
import mx.rpc.AbstractOperation;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.remoting.RemoteObject;
import mx.utils.StringUtil;
import org.xjh.events.FileUploadEvent;
/**
* FileReference 类提供了在用户计算机和服务器之间上载和下载文件的方法
* 每个 FileReference 对象都引用用户磁盘上的一个文件并且具有一些属性,
* 这些属性包含有关文件大小、类型、名称、创建日期、修改日期和创建者类型(仅限 Macintosh)的信息。
*/
private var fileReference:FileReference = new FileReference();
//存储要过滤文件类型的数组
private var _fileFilter:Array;
/**
* 设置文件过滤,打开文件选择框时选择哪些类型的文件
* FileFilter("Images (*.jpg, *.jpeg, *.gif, *.png)", "*.jpg;*.jpeg;*.gif;*.png")
*/
public function set fileFilter(fileType:String):void{
if(!StringUtil.isWhitespace(fileType) && StringUtil.trim(fileType).length > 3){
if(_fileFilter == null){
_fileFilter = [];
}
_fileFilter.push(new FileFilter("(" + fileType + ")", fileType));
}
}
//文件允许的最大大小: maxFileSize
private var _maxFileSize:Number = 1024*1024*20;
[Bindable]
/**
* 读取和设置文件最大尺寸,单位为Byte, 1K = 1024Byte,默认值为20M
*/
public function get maxFileSize():Number
{
return _maxFileSize;
}
public function set maxFileSize(size:Number):void
{
_maxFileSize = size;
}
//远程服务名称
private var _remoteServiceId:String = "";
/**
* 设置远程服务名称
*/
public function set remoteServiceId(remoteServiceId:String):void{
_remoteServiceId = remoteServiceId;
}
public function get remoteServiceId():String{
return _remoteServiceId;
}
//远程方法名称
private var _remoteMethodName:String = "";
/**
* 设置远程服务的文件上传方法名
*/
public function set remoteMethodName(remoteMethodName:String):void{
_remoteMethodName = remoteMethodName;
}
public function get remoteMethodName():String{
return _remoteMethodName;
}
//发送给远程服务对象的方法参数数组
private var _remoteMethodArgs:Array;
/**
* 设置发送到远程服务调用的方法参数
*/
public function set remoteMethodArgs(remoteMethodArgs:Array):void{
_remoteMethodArgs = remoteMethodArgs;
}
public function get remoteMethodArgs():Array{
return _remoteMethodArgs;
}
//页面元素渲染完成后调用的方法
private function init():void{
//为文件对象加入:“选择文件”事件监听器
fileReference.addEventListener(Event.SELECT, selectHandler);
//为文件对象加入:“完成上传”事件监听器
fileReference.addEventListener(Event.COMPLETE, completeHandler);
}
//上传完成后调用的方法
private function completeHandler(event:Event):void {
trace("completeHandler: " + event.toString());
}
//选择文件后调用的方法
private function selectHandler(event:Event):void {
this.txtFileInfo.text = fileReference.name; //文件名
this.txtFileInfo.toolTip = "文件大小: " + fileReference.size/1000 + "K"; //文件大小
fileReference.load(); //加载文件
}
/**
* 打开文件选择框的方法
*/
private function btnBrowse_clickHandler(event:MouseEvent):void
{
//打开文件选择框
fileReference.browse(_fileFilter);
}
//取消选择
private function btnDelete_clickHandler(event:MouseEvent):void
{
//删除远程服务器的文件
//清空txtFileInfo
txtFileInfo.text = "";
txtFileInfo.toolTip = "";
}
//当服务端正常完成文件上传之后所调用的方法
private function upload_resultHandler(event:ResultEvent):void
{
//将事件分派到事件流中。事件目标是对其调用 dispatchEvent() 方法的 EventDispatcher 对象
this.dispatchEvent(new FileUploadEvent(FileUploadEvent.RESULT, event.result));
}
//当服务端完成文件上传过程中出现了错误所调用的方法
private function upload_faultHandler(event:FaultEvent):void
{
//将事件分派到事件流中。事件目标是对其调用 dispatchEvent() 方法的 EventDispatcher 对象
this.dispatchEvent(new FileUploadEvent(FileUploadEvent.FAULT, null, event.fault));
}
/**
* 校验文件,包括是否选择了文件,文件大小
*/
public function checkFile():Boolean{
var checkResult:Boolean = true;
if(StringUtil.isWhitespace(txtFileInfo.text)){ //未选择文件
Alert.show("请选择要上传的文件!");
return false;
}
if(fileReference.size > _maxFileSize){ //文件大小验证失败
Alert.show(StringUtil.substitute("该文件尺寸{0} 超出最大尺寸 {1}.", fileReference.size/1000, _maxFileSize/1000));
checkResult = false;
}
if(fileReference.data == null){
Alert.show("文件正在加载中,请稍等!");
checkResult = false;
}
return checkResult;
}
/**
* 调用服务端的文件上传方法
*/
public function uploadFile():Boolean{
var isSuccess:Boolean = checkFile();
if(isSuccess){
//错误信息
var errorMessage:String;
//设置远程服务id,先用默认的
var serviceId:String = fileUpDownloadRemoteObj.destination;
if(remoteServiceId != null && "" != StringUtil.trim(remoteServiceId)){
serviceId = remoteServiceId;
}else{
errorMessage = "未给文件上传组件指定远程服务id(未给XjhFileUpload组件指定remoteServiceId属性)!";
trace(errorMessage);
throw new Error(errorMessage);
}
//设置远程服务Id
fileUpDownloadRemoteObj.destination = serviceId;
if(remoteMethodName == null || "" == StringUtil.trim(remoteMethodName)){
errorMessage = "未给文件上传组件指定调用的远程服务的方法名(未给XjhFileUpload组件指定remoteMethodName属性)!";
trace(errorMessage);
throw new Error(errorMessage);
return isSuccess = false;
}
//动态调用远程方法(根据远程方法名调用远程方法)
var remoteFunction:AbstractOperation = fileUpDownloadRemoteObj.getOperation(remoteMethodName);
if(remoteMethodArgs == null || remoteMethodArgs.length == 0){
trace("未给文件上传组件指定调用远程服务方法的参数数组!");
remoteFunction.send(fileReference.data,fileReference.name,fileReference.type);
}else{
//将文件内容作为第一个参数传入
remoteMethodArgs.unshift(fileReference.data);
//设置远程方法的另一些参数
remoteFunction.arguments = remoteMethodArgs;
remoteFunction.send();
}
}
return isSuccess;
}
]]>
</fx:Script>
<s:HGroup left="5" top="5">
<s:TextInput id="txtFileInfo" editable="false" width="150" />
<mx:Button label="选择" width="50" id="btnBrowse" click="btnBrowse_clickHandler(event)"
paddingLeft="3" paddingRight="3" />
<mx:Button label="取消" width="50" id="btnDelete"
labelPlacement="right" click="btnDelete_clickHandler(event)"
paddingLeft="3" paddingRight="3"/>
</s:HGroup>
</s:Group>
//FileUploadService.java
package org.xjh.service;
/**
*
* 功能:服务端文件上传服务组件
*/
public class FileUploadService {
private static final String SUCCESS_MSG = "文件?上传成功!";
private static final String UNSUCCESS_MSG = "文件?上传失败!";
public String uploadFile(byte[] datas, String fileName, String fileType){
String fileData = new String(datas);
System.out.println("文件名称:" + fileName);
System.out.println("文件类型:" + fileType);
System.out.println("文件内容:" + fileData);
return SUCCESS_MSG.replace("?", fileName);
}
}
4. 把文件上传服务组件FileUploadService配置到remoting-config.xml中去,让BlazeDS能找到并使用该组件。
<?xml version="1.0" encoding="UTF-8"?>
<service id="remoting-service" class="flex.messaging.services.RemotingService">
<adapters>
<adapter-definition id="java-object"
class="flex.messaging.services.remoting.adapters.JavaAdapter"
default="true" />
</adapters>
<default-channels>
<channel ref="my-amf" />
</default-channels>
<!-- 文件上传组件 -->
<destination id="fileUploadService">
<properties>
<source>org.xjh.service.FileUploadService</source>
<scope>request</scope>
</properties>
</destination>
</service>
5. 创建文件上传组件的测试文件FileUploadTest。
//FileUploadTest.mxml
<?xml version="1.0" encoding="utf-8"?>
<!--
功能:文件上传测试(通过BlazeDS与后台Java代码交互)
-->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
minWidth="955" minHeight="600"
creationComplete="init()"
xmlns:widget="org.xjh.components.*">
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import org.xjh.events.FileUploadEvent;
private function init():void{
}
private function uploadBT_clickHandler(event:MouseEvent):void
{
if(uploader.checkFile()) //文件校验
uploader.uploadFile(); //文件上传
}
private function uploader_resultHandler(event:FileUploadEvent):void
{
Alert.show(event.result.toString());
}
private function uploader_faultHandler(event:FileUploadEvent):void
{
Alert.show("文件上传失败:" + event.fault.faultString);
}
]]>
</fx:Script>
<fx:Declarations>
</fx:Declarations>
<s:VGroup left="10" y="10">
<!--
fileFilter限定文件类型(非必须填),remoteServiceId指定配置文件为远程服务组件配置的id(必填),
remoteMethodName指定远程服务组件完成文件上传的方法名称(必填),
remoteMethodArgs指定远程服务组件完成文件上传的方法参数(非必填,但方法参数类型和个数必须与服务端服务方法匹配),
result指定了成功完成文件上传后所调用的方法,fault指定了文件不能正常完成上传所调用的方法
-->
<widget:XjhFileUploader id="uploader" fileFilter="*.txt" remoteServiceId="fileUploadService" remoteMethodName="uploadFile"
result="uploader_resultHandler(event)" fault="uploader_faultHandler(event)"/>
<s:HGroup>
<s:Button id="uploadBT" click="uploadBT_clickHandler(event)" label="上传" />
</s:HGroup>
</s:VGroup>
</s:Application>
6.1 选择文件
6.2 点击“上传”按钮
6.3 控制台打印提示信息