Adobe Flex 3.5 : UploadDownloadBlazeDS

domingo, 28/03/2010 1:00 am  

Publicando mais uma dica, algo que uso em alguns projetos, transferir arquivos entre a aplicação Adobe Flex e o Servidor, nesse caso Java (BlazeDS), segue…

Eia a interface da aplicação com a implementação da funcionalidade:

UploadDownloadBlazeDS_layout

Para essa implementação foi utilizado:

- Adobe Flex Builder 3 (instalado o plugin no Eclipse Ganymede JEE)

- Adobe Flex 3.5 SDK

- Adobe Flash Player 10+

- BlazeDS 3 

- Java 1.5+

- Apache Tomcat 6+

 

Estrutura do projeto:

UploadDownloadBlazeDS_Projeto

Observe que dentro de WebContent, criei o diretório files_dir, para receber os arquivos e a partir deste diretório listar e efetuar o download dos arquivos, para este exemplo.

 

Funcionalidades implementadas do projeto:

- Upload de um arquivo

- Listagem dos arquivos no diretório de arquivos da aplicação

- Download de um arquivo especificado

- Apagar um arquivo especificado

Segue o código da classe Java que implementa as funcionalidades:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package com.erkobridee.blazeds.util;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.List;
 
import flex.messaging.FlexContext;
 
/**
 * @author Erko Bridee
 * @description Classe de gerenciamento de arquivos
 *
 */
public class FileUtils {
 
	private String dirPath = "files_dir";
 
	/**
	 * Método para receber um arquivo
	 *
	 * @param bytes byte[]
	 * @param fileName String
	 * @return String
	 * @throws Exception
	 */
	public String  doUpload(
			byte[] bytes, // bytes do arquivo
			String fileName // nome do arquivo
	) throws Exception {
		fileName = FlexContext.getServletContext().getRealPath(dirPath + "/" + fileName);
 
		System.out.println("doUpload: " + fileName);
 
		File f = new File(fileName);
		FileOutputStream fos = new FileOutputStream(f);
		fos.write(bytes);
		fos.close();
		return "success";
	}
 
	/**
	 * Retorna a listagem dos arquivos disponíveis
	 *
	 * @return List<FileInfo>
	 */
	public List<FileInfo> getDownloadList() throws Exception {
 
		System.out.println(FlexContext.getServletContext().getRealPath(dirPath));
 
		File dir = new File(FlexContext.getServletContext().getRealPath(dirPath));
 
		File[] files = dir.listFiles();
		List<FileInfo> dirList = new ArrayList<FileInfo>();
 
		if (files == null) {
			// caso o diretório não exista ou o caminho seja um diretório
		} else {
			for (int i=0; i<files.length; i++) {
				FileInfo info = new FileInfo();
 
				info.setName( files[i].getName() );
				info.setLength( files[i].length() );
 
				dirList.add( info );
			}
		}
		return dirList;
	}
 
	/**
	 * Método que recupera um arquivo e retorna seus bytes
	 *
	 * @param fileName
	 * @return byte[]
	 */
	public byte[] doDownload(String fileName) {
 
		System.out.println("doDownload: " + fileName);
 
		FileInputStream fis;
		byte[] data =null;
		FileChannel fc; 
 
		try {
			fileName = FlexContext.getServletContext().getRealPath(dirPath + "/" + fileName);
 
			fis = new FileInputStream(fileName);
			fc = fis.getChannel();
			data = new byte[(int)(fc.size())];
			ByteBuffer bb = ByteBuffer.wrap(data);
			fc.read(bb);
		} catch (FileNotFoundException e) {
			// TODO
		} catch (IOException e) {
			// TODO
		}
		return data;
	}	
 
	/**
	 * Método para apagar um determinado arquivo
	 *
	 * @param filename String
	 * @return String
	 */
	public String doDelete(String fileName) {
		String message = "fail";
 
		fileName = FlexContext.getServletContext().getRealPath(dirPath + "/" + fileName);
 
		System.out.println("doDelete: " + fileName);
 
		File file = new File(fileName);
		if( file.exists() ) {
			if( file.delete() ) {
				message = "success";
			}
		} 
 
		return message;
	}
 
}

 

Essa classe é mapeada como um serviço do BlazeDS no arquivo /WebContent/WEB-INF/flex/remoting-config.xml :

1
2
3
4
5
<destination id="fileUtilService">
<properties>
		<source>com.erkobridee.blazeds.util.FileUtils</source>
	</properties>
</destination>

 

No lado da aplicação Flex, foram definidos 2 componetes.

 

Upload:

?View Code ACTIONSCRIPT3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
<mx:Panel
	xmlns:mx="http://www.adobe.com/2006/mxml"
	layout="vertical"
	width="100%"  height="100%"
	title="Upload : Arquivos">
 
	<mx:Script>
		<![CDATA[
			import vo.FileInfo;
			import mx.controls.Alert;
			import mx.rpc.AsyncToken;
			import mx.rpc.events.FaultEvent;
			import mx.rpc.events.ResultEvent;
 
			private var refUploadFile:FileReference;
 
			private var UploadFiles:Array = new Array();
 
			/*
				Chamado para adicionar os arquivos para upload
			*/
			private function addFiles():void {
				var FILE_FILTER_ALL_FILES_TYPE:Array = [new FileFilter("All files", "*.*")];
 
				refUploadFile = new  FileReference();
	  			refUploadFile.browse(FILE_FILTER_ALL_FILES_TYPE);
	  			refUploadFile.addEventListener(Event.SELECT,onFileSelect);
	  			refUploadFile.addEventListener(Event.COMPLETE,onFileComplete);
 
	  			refUploadFile.addEventListener(IOErrorEvent.IO_ERROR, frIOError);
    			refUploadFile.addEventListener(SecurityErrorEvent.SECURITY_ERROR, frSecError);
 
			}
 
			/*
				Chamado quando os arquivos são selecionado
			*/
			private function onFileSelect(event:Event):void {
 
				UploadFiles.push({
					name:refUploadFile.name,
					size:FileInfo.formatFileSize(refUploadFile.size),
					status:"inicial"
				});
 
				listFiles.dataProvider  = UploadFiles;
				listFiles.selectedIndex = UploadFiles.length - 1;
 
				try {
					refUploadFile.load();
				} catch( err:IOErrorEvent ) {
					Alert.show("erro");
				}
 
				for ( var i:int = 0 ; i <  UploadFiles.length ; i++ ) {
					if( UploadFiles[i].name == refUploadFile ) {
						UploadFiles[i].status = "carregado";
						listFiles.dataProvider  = UploadFiles;
						break;
					}
				}
			}
 
			/*
				Chamado quando for formatar a representação do tamanho do arquivo
			*/
			private function formatFileSize(numSize:Number):String {
				var strReturn:String;
				numSize = Number(numSize / 1000);
				strReturn = String(numSize.toFixed(1) + " KB");
				if (numSize > 1000) {
					numSize = numSize / 1000;
					strReturn = String(numSize.toFixed(1) + " MB");
					if (numSize > 1000) {
						numSize = numSize / 1000;
						strReturn = String(numSize.toFixed(1) + " GB");
					}
				}
				return strReturn;
			}
 
			private function onFileComplete(event:Event):void {
 
				refUploadFile = event.currentTarget as FileReference;
				var data:ByteArray = refUploadFile.data;  
 
				var token:AsyncToken = AsyncToken(
					remoteUpload.doUpload(data, refUploadFile.name)
				);
 
				token.kind = refUploadFile.name;
 
				for ( var i:int = 0 ; i <  UploadFiles.length ; i++ ) {
					if( UploadFiles[i].name == refUploadFile ) {
						UploadFiles[i].status = "enviando";
						listFiles.dataProvider  = UploadFiles;
						break;
					}
				}
			}
 
	  		private function uploadResultHandler(event:ResultEvent):void {
				for ( var i:int = 0 ; i <  UploadFiles.length ; i++ ) {
					if( UploadFiles[i].name == event.token.kind ) {
						UploadFiles[i].status = "OK";
						listFiles.dataProvider  = UploadFiles;
						break;
					}
				}
	  		}
 
	  		private function faultResultHandler(event:FaultEvent):void {
				for ( var i:int = 0 ; i <  UploadFiles.length ; i++ ) {
					if( UploadFiles[i].name == event.token.kind ) {
						UploadFiles[i].status = "erro";
						listFiles.dataProvider  = UploadFiles;
						break;
					}
				}
	  		}
 
			private function frIOError(evt:IOErrorEvent):void{
			    Alert.show(evt.toString());
			}
 
			private function frSecError(evt:SecurityErrorEvent):void{
			    Alert.show(evt.toString());
			}
 
			private function clearUploadList():void {
				UploadFiles = null;
				UploadFiles = new Array();
				listFiles.dataProvider = UploadFiles;
			}
 
		]]>
	</mx:Script>
 
	<mx:RemoteObject
		id="remoteUpload"
		destination="fileUtilService"
		result="uploadResultHandler(event)"
		fault="faultResultHandler(event)"/>
 
	<mx:Canvas width="100%" height="100%">
		<mx:DataGrid id="listFiles" left="0" top="0" bottom="0" right="0"
			allowMultipleSelection="true" verticalScrollPolicy="on"
			draggableColumns="false" resizableColumns="false" sortableColumns="false">
			<mx:columns>
				<mx:DataGridColumn headerText="Arquivo" width="150" dataField="name" wordWrap="true"/>
				<mx:DataGridColumn headerText="Tamanho" width="50" dataField="size" textAlign="right"/>
				<mx:DataGridColumn headerText="Status" width="50" dataField="status" textAlign="right"/>
			</mx:columns>
		</mx:DataGrid>
	</mx:Canvas>
	<mx:ControlBar horizontalAlign="center" verticalAlign="middle">
		<mx:Button
			id="btnAdd"
			toolTip="Adicionar arquivo(s)"
			click="addFiles()"
			label="Upload : Arquivo(s)"
			width="150"/>
		<mx:Button
			label="Limpar lista"
			click="{clearUploadList()}"/>
	</mx:ControlBar>
 
</mx:Panel>

 

Download:

?View Code ACTIONSCRIPT3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
<mx:Panel
	xmlns:mx="http://www.adobe.com/2006/mxml"
	layout="vertical"
	width="100%" height="100%"
	title="Download : Arquivos">
 
	<mx:Script>
		<![CDATA[
 
			import mx.controls.Alert;
			import mx.collections.ArrayCollection;
			import mx.rpc.events.FaultEvent;
			import mx.rpc.events.ResultEvent;
			import mx.rpc.AsyncToken;
 
			private var downloadFiles:ArrayCollection = new ArrayCollection();
			private var downloadFilesColl:ArrayCollection = new ArrayCollection();
			private var fileData:ByteArray = new ByteArray();
			private var fileName:String;
 
			private function downloadResultHandler(event:ResultEvent):void {
				if ( event.token.kind == "remoteFileList") {
					downloadFiles.removeAll();
					downloadFilesColl = event.result as ArrayCollection;
					for ( var i:int = 0 ; i <  downloadFilesColl.length ; i++ ) {
						downloadFiles.addItem({
							name:downloadFilesColl[i].name,
							size:downloadFilesColl[i].size,
							status:"Inicial"
						});
					}
					listFiles.dataProvider = downloadFiles;
				} else if(event.token.kind == "remoteDeleteFile") {
					Alert.show( event.result as String );
					getRemoteFiles();
				} else  {
					fileData = event.result as ByteArray;
					fileName = event.token.kind;
 
					Alert.show(fileName);
 
					for ( var b:int = 0 ; b <  downloadFiles.length ; b++ ) {
						if( downloadFiles[b].name == event.token.kind ) {
							downloadFiles[b].status = "Pronto";
							listFiles.dataProvider  = downloadFiles;
							break;
						}
					}
				}
			}
 
			private function faultResultHandler(event:FaultEvent):void {}
 
			private function saveFile():void {
				var fileReference:FileReference = new FileReference();
				fileReference.save(fileData,fileName);
			}
 
			private function getRemoteFiles():void {
				var token:AsyncToken = AsyncToken(remoteDownload.getDownloadList());
				token.kind = "remoteFileList";
			}
 
			private function getDownload():void {
				var token:AsyncToken = AsyncToken(remoteDownload.doDownload(listFiles.selectedItem.name));
				token.kind = listFiles.selectedItem.name;
			}
 
			private function doDelete():void {
				var token:AsyncToken = AsyncToken(remoteDownload.doDelete(listFiles.selectedItem.name));
				token.kind = "remoteDeleteFile";
			}
		]]>
	</mx:Script>
 
	<mx:RemoteObject
		id="remoteDownload"
		destination="fileUtilService"
		result="downloadResultHandler(event)"
		fault="faultResultHandler(event)"
		showBusyCursor="true"/>
 
	<mx:Canvas width="100%" height="100%">
		<mx:DataGrid id="listFiles" left="0" top="0" bottom="0" right="0"
			verticalScrollPolicy="on"
			draggableColumns="false" resizableColumns="false" sortableColumns="false">
			<mx:columns>
				<mx:DataGridColumn headerText="Arquivo" width="150" dataField="name" wordWrap="true"/>
				<mx:DataGridColumn headerText="Tamanho" width="50" dataField="size" textAlign="right"/>
				<mx:DataGridColumn headerText="Status" width="50" dataField="status" textAlign="right"/>
			</mx:columns>
 
		</mx:DataGrid>
	</mx:Canvas>
	<mx:ControlBar horizontalAlign="center" verticalAlign="middle">
		<mx:Button id="btnList" toolTip="Listar arquivos remotos"
			label="Listar arquivos"
			click="getRemoteFiles()"/>
		<mx:Button id="btnRetrieve" toolTip="Pegar arquivo"
			 click="getDownload()" label="Pegar arquivo"/>
		<mx:Button id="btnSave" toolTip="Salvar arquivo"
			 click="saveFile()" label="Salvar arquivo"/>
		<mx:Button label="Apagar arquivo" click="doDelete()"/>
	</mx:ControlBar>
 
</mx:Panel>

 

Considerações:

Esta forma de transferir arquivos  pode-lhe ser útil, assim como para mim o foi, onde em um caso eu precisava enviar uma coleção de objetos para o Java, sendo dessa coleção de dados gerados um relatório através do Jasperreports, onde o PDF me retorna via a funcionalidade de download apresentada nesse exemplo.

 

Download projeto: [UploadDownloadBlazeDS]

obs.:
– em Adobe Flex Builder 3
– sem as libs do BlazeDS [efetuar o download e acrescentar no projeto para executar]

, , , , , , ,

Este post foi escrito por:

- que escreveu 499 post(s).


Entre em contato