I am trying to add a client side progress bar to
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.
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.