Friday, February 26, 2010

File upload with Flex and Spring

Last I wrote how to connect Flex with Spring. Now I have decided to create an example of uploading multiple files via BlazeDS and here I will show it to you.

You can see the new article on browse and download with Flex, Spring and BlazeDS


So in the example we have 2 buttons (browse and upload) and a data grid  that will display the selected files.

<s:Button label="Browse Files" click="browseFiles(event)" />
<mx:DataGrid id="dataGrid" width="200">
    <mx:columns>
        <mx:DataGridColumn headerText="Selected files"/>
    </mx:columns>
</mx:DataGrid>
<s:Button label="Upload Files" click="uploadFiles(event)"/>

When the first button is clicked we call the browseFiles function that creates an instance of FileReferenceList and opens up the file dialog for browsing.

private function browseFiles(event:MouseEvent):void
{
    fileRefList = new FileReferenceList();
    fileRefList.addEventListener(Event.SELECT, selectFiles);
    fileRefList.browse();
}

Now when the user selected some files and presses "open", the function selectFiles is called
private function selectFiles(e:Event):void
{                
    for each(var fileRef : FileReference in fileRefList.fileList)
    {
        fileRef.load();
        selectedFiles.push(fileRef.name);
        selectedFileReferences.push(fileRef);
    }
    dataGrid.dataProvider = selectedFiles;
}


It iterates over the list of FileReference (the selected files) and for each it loads the file, adds its name to an array of strings, that we use to show in the data grid and to an array that holds the selected file references, so that we can add more on another pressing of "browse"


Now we should be able to see our data grid filled with names of files.
The next thing to do is to create a function for handling the click of the "Upload Files"  button.

private function uploadFiles(e:MouseEvent):void
{                
    for each(var fileRef : FileReference in selectedFileReferences)
    {
        remoteObjectUpload.doUpload(fileRef.name, fileRef.data);
    }
}

For each FileRefernce we call our remote method by passing the file's name and the file's data represented by BytesArray.
The actual Java class and method looks like:

@Service("fileUploadService")
@RemotingDestination(channels = {"my-amf"})
public class FileUploadService {

    //change this to the desired path you wish the files to be uploaded
    private static String File_Path = "C:\\workspace\\Temp\\";
    @RemotingInclude
    public static Boolean doUpload(String fileName, byte[] data) {
        try{
            //create the dir that we will store files
            File dir = new File(File_Path);
            dir.mkdirs();
            
            File file = new File(File_Path + fileName);
            FileOutputStream output = new FileOutputStream(file);
            output.write(data);
            output.close();
        }
        catch(FileNotFoundException e){
            return false;
        }
        catch(IOException e){
            return false;
        }
    
        return true;
    }
}

The doUpload method just creates the directories to the File_Path, creates a new output stream for the given file and writes the bytes.

And aggain you can see the other scenario - downloading the files

You can download the files for both Spring and Flex projects from here:
FileUpload.zip

EDIT: From the Spring project I have made a Maven 2 project, so that you can also download