JavaScript Upload (POST) with HTML5 File API to Play Action

749 views
Skip to first unread message

Riyad

unread,
Jun 6, 2010, 8:06:10 PM6/6/10
to play-framework
Disclaimer: I'm about 17mins into Play! so please excuse unforgivable
errors.

I am following up on a tutorial I wrote on how to get started with the
new HTML5 DnD & File API's - http://www.thebuzzmedia.com/html5-drag-and-drop-and-file-api-tutorial/
- with a Play! application to try and provide an immediate Drag-and-
Drop file upload experience for local files.

The part I'm getting stuck on (and this is where my newness is going
to hang me) is my XMLHttpRequest POST to the repsective Play! action:
---------------------
var client = new XMLHttpRequest();

client.open("POST", "/upload");
client.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
client.send(evt.target.result);
---------------------

with a route that looks like:
---------------------
POST /upload
Application.upload
---------------------

and an action that looks like:
---------------------
public static void upload(File upload) {
System.out.println("Uploaded: " + upload);
}
---------------------

The part I'm confused on:

1. Is this even the right way to do this? I'm pretty new to fancy
JavaScript as well.
2. What signature should my upload() method have to grab the uploaded
bytes? I've tried "byte[]" and "File" and "String" -- I'm just not
clear on the binding rules. I want to support uploading binary files
as well as text files... if that is important?
3. One last step I'll need is a redirect after the post to another
Play! page displaying a summary for the upload... I *think* that means
in my upload(..) action calling another action that does a redirect to
another action with the interesting args in it that the template will
render... just want to make sure that is right.

Any help to clear this fog would be appreciated. I searched quite a
bit but "javascript file upload" or "javascript post upload" doesn't
turn up anything and "file upload" turns up umpteen pages.

Thank you.

gren

unread,
Jun 7, 2010, 4:15:07 AM6/7/10
to play-framework
Hi,
1.
Usage example in javascript :
var formdata = new FormData();
formdata.append(name, file);
beforeUpload();
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
onSuccessUpload(xhr.responseText, xhr.readyState);
};
xhr.open(method, action);
xhr.send(formdata);

2.
you can use a File in your controller signature. It doesn't matter if
your file is binary or text.

3.
You upload your file in a asynchronous way with javascript. I think
you better manage the redirect in javascript. By the way, you could
embedding your file upload in a main form, user will be able to
validate/delete/overwrite the uploaded (like gmail attachment).

PS : I have develop a similar app which could help you :
http://github.com/gre/HTML5-File-Uploader

On Jun 7, 2:06 am, Riyad <rka...@gmail.com> wrote:
> Disclaimer: I'm about 17mins into Play! so please excuse unforgivable
> errors.
>
> I am following up on a tutorial I wrote on how to get started with the
> new HTML5 DnD & File API's -http://www.thebuzzmedia.com/html5-drag-and-drop-and-file-api-tutorial/

Riyad

unread,
Jun 7, 2010, 4:07:01 PM6/7/10
to play-framework
Gren,

Thanks so much for the reply -- especially the app example.

I'm heading out at the moment, but for anyone else interested in this
thread, what I have now in my App controller method is:

---------------
public static void upload() throws IOException {
BufferedReader r = new BufferedReader(new
InputStreamReader(request.body));
System.out.println("Uploaded: " + r.readLine());
}
---------------

I don't know what the binding rules are, but I was unable to get Play!
to bind to a byte[], File or any other argument for that method, so I
just pulled the input stream directly from the request and read it in.


Also got the listener for onreadystatechange just as you mentioned
working. I'll take a look at your code when I get a chance, I have a
feeling you probably did it a lot nicer than I have thus far ;)

Guillaume Bort

unread,
Jun 7, 2010, 4:12:22 PM6/7/10
to play-fr...@googlegroups.com
FIle upload only work with multipart/form-data as content type.
Otherwise you have to read the raw stream as you did.

> --
> You received this message because you are subscribed to the Google Groups "play-framework" group.
> To post to this group, send email to play-fr...@googlegroups.com.
> To unsubscribe from this group, send email to play-framewor...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/play-framework?hl=en.
>
>

Riyad

unread,
Jul 7, 2010, 3:57:22 PM7/7/10
to play-framework
For anyone that finds this thread, it eventually turned into a long
HTML 5 File API/Drag and Drop tutorial I wrote up here:
http://www.thebuzzmedia.com/html5-drag-and-drop-and-file-api-tutorial/

Right now Firefox 3.6 is the only one that supports it with Chrome
supporting it in the nightlies and Safari likely to support it in 5.1.
Time will tell.

The Play! portion would come in with the drop handler streaming the
base64-encoded image data over to a Play action to handle instead of
re-inserting it directly into the page again as an image like the
tutorial does incase anyone is walking through this.

Enjoy!
> >> > to hang me) is my XMLHttpRequestPOSTto the repsective Play! action:
> >> > ---------------------
> >> > var client = new XMLHttpRequest();
>
> >> > client.open("POST", "/upload");
> >> > client.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
> >> > client.send(evt.target.result);
> >> > ---------------------
>
> >> > with a route that looks like:
> >> > ---------------------
> >> >POST    /upload
> >> > Application.upload
> >> > ---------------------
>
> >> > and an action that looks like:
> >> > ---------------------
> >> > public static void upload(File upload) {
> >> >         System.out.println("Uploaded: " + upload);}
>
> >> > ---------------------
>
> >> > The part I'm confused on:
>
> >> > 1. Is this even the right way to do this? I'm pretty new to fancy
> >> > JavaScript as well.
> >> > 2. What signature should my upload() method have to grab the uploaded
> >> > bytes? I've tried "byte[]" and "File" and "String" -- I'm just not
> >> > clear on the binding rules. I want to support uploading binary files
> >> > as well as text files... if that is important?
> >> > 3. One last step I'll need is a redirect after thepostto another
> >> > Play! page displaying a summary for the upload... I *think* that means
> >> > in my upload(..) action calling another action that does a redirect to
> >> > another action with the interesting args in it that the template will
> >> >render... just want to make sure that is right.
>
> >> > Any help to clear this fog would be appreciated. I searched quite a
> >> > bit but "javascript file upload" or "javascriptpostupload" doesn't
> >> > turn up anything and "file upload" turns up umpteen pages.
>
> >> > Thank you.
>
> > --
> > You received this message because you are subscribed to the Google Groups "play-framework" group.
> > Topostto this group, send email to play-fr...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages