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.



    
        
    

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

16 comments

  1. Helen Neely · February 28, 2010

    Nice and short article –
    But it would have been better if you made the file path platform neutral, what you have there is Windows specific. Although it works, it will need tweaking before it can run on Linux and Mac OSX.

    Nice example btw 🙂

    Like

  2. Tony Georgiev · February 28, 2010

    Helen, thanks for the good words and thanks for the tip! As you said the path really is set for my machine, for Windows. As this is just an example I think it will be better for the people using it to set the path their selves. One reason, as you said, is about the specific OS, another reason the writing permissions the user has over the folder and off course the desire where to put the temp files. I will leave it that way, but will add comment in the code to change the path.
    Thanks

    Like

  3. Anonymous · March 5, 2010

    thank u for ur article.

    Like

  4. Books In Order · March 5, 2010

    Actually, that's a good idea. It provides the users the opportunity to make it run on their individual platforms. Again it allows beginners to get their hands dirty – in the process learning between Windows and Linux file systems in Java.

    Great post.

    Like

  5. Tony Georgiev · March 7, 2010

    The simplest solution is to set File_Path = System.getProperty(“user.home”) . This will point to user's home directory for Windows, Linux and OSX

    Like

  6. f5refresh · May 7, 2010

    Congratz Tony… very good post, help me alot!

    Like

  7. alias · August 11, 2010

    I've been looking for a simple upload example, but always they were thousands lines of length…
    thank you for this quick tut!

    enemyleft

    Like

  8. Abhishek · December 3, 2010

    Excellent article!!

    Thanks Tony.

    I was wondering if I had to first send each file from Flex client to the server(to be treated as mail attachments), and then send the text (to be included as the mail body) and then retrieve all the files sent earlier and finally assembling them all to send the mail.

    Your article gave me great pointers to send them all at one go.

    Thanks a ton Tony

    Like

  9. adi · January 11, 2011

    hi,
    very nice blog. but I have problem as I am using Flex-Spring-BlazeDs sdk 3.5 and its a project need. .load() could not get recognized by compiler. so I tried with upload() with .cfm file but still I not able to solve it. I will really appreciate if you give some example of this case.

    thank u

    Like

  10. francis · March 4, 2011

    Hi,

    How to set String File_Path to application context root

    Like

  11. Tony Georgiev · September 29, 2011

    Adi, load() is supported in FlashPlayer 10 and up. The problem is not in the sdk, but the player version.

    Francis, try this FlexContext.getServletContext().getRealPath(“/”)

    Like

  12. Anonymous · February 9, 2012

    Hi,
    I am using the same thing in my project Flex+Spring, and trying to upload image data using ByteArray. But Getting an error:
    [BlazeDS]Serializing AMF/HTTP response
    Version: 3
    (Message #0 targetURI=/2/onStatus, responseURI=)
    (Typed Object #0 'flex.messaging.messages.ErrorMessage')
    headers = (Object #1)
    rootCause = null
    body = null
    correlationId = null
    faultDetail = null
    faultString = “Creation validation for class '[B' failed.”
    clientId = null
    timeToLive = 0.0
    destination = null
    timestamp = 1.328734836964E12
    extendedData = null
    faultCode = “Client.Message.Encoding”
    messageId = “4C5DF944-A409-A4DA-EB2D-5D00246EF874”

    I have a Dto on flex side which contains property “public var logo:ByteArray;”,
    And the corresponding java side property for the Dto is “public byte[] logo;”.

    While transferring this dto from flex to java, blazeDS fails and below log is displayed on the blazeDS side.

    *Any pointers will be a great help*

    ——LOG——
    [BlazeDS]Serializing AMF/HTTP response
    Version: 3
    (Message #0 targetURI=/1/onResult, responseURI=)
    (Externalizable Object #0 'DSK')
    (Object #1)
    DSMessagingVersion = 1.0
    DSId = “4C5DF8B4-9918-12A2-68F7-ECE9576CC80F”
    1.328734836905E12
    (Byte Array #2, Length 16)
    (Byte Array #3, Length 16)
    (Byte Array #4, Length 16)

    [BlazeDS]Creation validation for class '[B' failed.
    flex.messaging.io.SerializationException: Creation validation for class '[B' failed.
    at flex.messaging.util.ClassUtil.validateCreation(ClassUtil.java:347)
    at flex.messaging.io.amf.Amf3Input.readByteArray(Amf3Input.java:507)
    at flex.messaging.io.amf.Amf3Input.readObjectValue(Amf3Input.java:213)
    at flex.messaging.io.amf.Amf3Input.readObject(Amf3Input.java:130)
    at flex.messaging.io.amf.Amf3Input.readScriptObject(Amf3Input.java:437)
    at flex.messaging.io.amf.Amf3Input.readObjectValue(Amf3Input.java:152)
    .
    .
    .

    Like

  13. Anonymous · February 10, 2012

    Thanks Tony,

    Didn't found the Reason of the problem! 😦
    So instead of “ByteArray” used plain “String” and converted byteArray to sting using Base64Encoder.encodeBytes();

    Hope this will help some one!

    Like

  14. sumant kumar · March 12, 2013

    Hi ,

    I am getting this problem

    [BlazeDS]Creation validation for class 'com.brocade.dcm.vmplugin.service.layer.model.NetworkAdvisorServiceRequest' failed

    flex.messaging.io.SerializationException: Creation validation for class 'com.brocade.dcm.vmplugin.service.layer.model.NetworkAdvisorServiceRequest' failed.

    Could you please help me to find out the root cause

    Like

  15. 陈续缘 · July 19, 2013

    thank U!

    Like

Leave a comment