After some research this is a little more complicated than it first appears.
JSF and multiple files
First of all, JSF 2.2 defines <h:inputFile>
tag which is limited to a single file, i.e. it does not support HTML5 parameter multiple=true
. See this for more details. On the other hand, it is very easy to extend this tag to allow multiple files since the uploaded files are fetched from the request
, so they are easily available.
Where are the files parsed and persisted?
All JSF requests are handled by the FacesServlet
, which is annotated with Servlet's 3.1 tag @MultipartConfig
. This annotation basically does all the heavy lifting of extracting and writing the uploaded files. See this and this.
Although this is very handy and takes care of most things, it doesn't have a progress listener interface, which means that you will get the files (Parts
) when they are fully uploaded. I don't see a way to actually intercept this is a clean way in order to implement a server-side progress bar.
Server-side Vs Client-side progress listener
In order to implement a server side progress listener, you will need somehow to handle files yourself and notify the user about the progress using polling
or WebSockets.
For the client-side, you will need to either write a custom POST
function like this or use a library like this this to handle the POST
as most browsers don't provide progress information. Basically, instead of using the browsers functionality to do a post (AFAIK) you handle the request yourself and hence you have control of the bytes transferred. The problem here is that FacesServlet
expects a request which is formatted by the jsf.js
functions and I do not see an easy way to intercept the JS
request just for processing file upload.
What are my options then?
I would safely suggest using an existing library that offers this functionality.
If you have the time and still want to DIY, I think that the best way to go is to write your own FileUploadServlet
that 'understands' JSON or XHR and use a JQuery
plugin to initiate the upload and provide the client-side progress bar.
Example
I have finally decided to go with JQuery/blueimp fileupload. See this comment for details. Note, that this is not actually part of the normal JSF Flow, I developed a custom way for feeding the actual parts in my application.
PS. As I am new to this, don't read this answer as a definitive answer but as a starting point for your own research.