2

I am trying to add a client side progress bar to JSF2.2 ajax requests. What I would ideally like to do is get the request header size and receive updates for the status of the POST.

I do not know a lot about JS/JQuery but as far as I can tell, JQuery must initiate the request in order to achieve this(see here)

Is there a way to do this from the client-side only?

If this is not possible, what other (native) options do I have?

Thanks,

PS1. Although the main scope for this, is a file upload progress bar, I would like to be able to apply on the full request size. PS2. I know there are a few libraries that offers this for free, but ATM I don't wan't to use any.

Community
  • 1
  • 1
Ioannis Deligiannis
  • 2,679
  • 5
  • 25
  • 48

2 Answers2

3

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.

Community
  • 1
  • 1
Ioannis Deligiannis
  • 2,679
  • 5
  • 25
  • 48
1

I found that the Malsup Form plugin for jQuery is fairly simple and has good documentation and demo code (therefore fairly easy to use to Ajaxify a progress bar) if you want to go the jQuery (Javascript) route, which keeps things on the client side.

(Of course, other plugins also exist, like the BlueImp file uploader plugin which has a lot more possibilities, but may not be quite that easy to use.)

For a "JSF-only" solution, BalusC recommends using a JSF component library like Primefaces - which is probably a better option - it is recommended to read his comments and links he provides which explain reasoning behind the preference for one technology over the other.

Community
  • 1
  • 1
frIT
  • 3,213
  • 1
  • 18
  • 22