7

I have a Java desktop client application that uploads files to a REST service.

All calls to the REST service are handled using the Spring RestTemplate class.

I'm looking to implement a progress bar and cancel functionality as the files being uploaded can be quite big.

I've been looking for a way to implement this on the web but have had no luck.

I tried implementing my own ResourceHttpMessageConverter and substituting the writeInternal() method but this method seems to be called during some sort of buffered operation prior to actually posting the request (so the stream is read all in one go before sending takes place).

I've even tried overriding the CommonsClientHttpRequestFactory.createRequest() method and implementing my own RequestEntity class with a special writeRequest() method but the same issue occurs (stream is all read before actually sending the post).

Am I looking in the wrong place? Has anyone done something similar.

A lot of the stuff I've read on the web about implementing progress bars talks about staring the upload off and then using separate AJAX requests to poll the web server for progress which seems like an odd way to go about it.

Any help or tips greatly appreciated.

glidester
  • 599
  • 6
  • 23
  • this might have what you are looking for http://stackoverflow.com/questions/5294532/httpclient-upload-big-file-and-show-sent-bytes-number – ams Dec 15 '12 at 05:00
  • 1
    Thanks for the link. Unfortunately the example given uses the low level apache libraries so I'm not clear what the equivalent FileBody class would be in the Spring Rest libraries, or how I could inject my own implementation for them to use. – glidester Dec 21 '12 at 10:31

2 Answers2

1

This is an old question but it is still relevant.

I tried implementing my own ResourceHttpMessageConverter and substituting the writeInternal() method but this method seems to be called during some sort of buffered operation prior to actually posting the request (so the stream is read all in one go before sending takes place).

You were on the right track. Additionally, you also needed to disable request body buffering on the RestTemplate's HttpRequestFactory, something like this:

HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
clientHttpRequestFactory.setBufferRequestBody(false);
RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory);

Here's a working example for tracking file upload progress with RestTemplate.

ElectroBuddha
  • 630
  • 10
  • 20
  • Thanks for this info, sounds like what I was after. 10 years too late but better late than never . Hopefully it will help other though – glidester Jan 09 '22 at 22:03
0

There was not much detail about what this app is, or how it works so this response is vague but I believe you can do something like this to track your upload progress.

If this really is a Java Client App (i.e. Not HTML/JavaScript but a java program) and you really are having it upload a file as a stream then you should be able to track your upload progress by counting the bytes in the array being transmitted in the stream buffer and comparing that to the total byte count from the file object.

When you get the file get its size.

Integer totalFile = file.getTotalSpace();

Where ever you are transmitting as a stream you are presumably adding bytes to a output buffer of some kind

byte[] bytesFromSomeFileReader =  [whatEverYouAreUsingToReadTheFile];

    ByteArrayOutputStream byteStreamToServer = new ByteArrayOutputStream();
    Integer bytesTransmitted = 0;

    for (byte fileByte : bytesFromSomeFileReader) {
        byteStreamToServer.write(fileByte);
            //
            //  Update your progress bar every killo-byte sent.
            //
        bytesTransmitted++;
        if( (bytesTransmitted % 1000) = 0) {
            someMethodToUpdateProgressBar();
        }
    }
BrianC
  • 1,793
  • 1
  • 18
  • 26
  • Sorry but this doesn't help. In principle this solution is sound but as I stated in the OP the stream seems to be completely read *before* the upload commences. So the progress bar would whiz to 100% and then sit there for however long the upload took. – glidester Oct 22 '15 at 11:35
  • ??? How is it read BEFORE the upload? That is not possible. As stated no details were given has to what is being done or how. You would have to give actual details provide a more detailed answer. – BrianC Oct 22 '15 at 16:10
  • Also if we are talking about the client here how is the stream read? It should be written from the client. – BrianC Oct 22 '15 at 16:11
  • The stream I'm referring to is the file input stream of the local file that is being uploaded to the remote server. I can't provide any details now as this was a project I worked on 2 years ago! As I said in the OP I believed that the content to be uploaded was being buffered, so the streams were completely read/written before any network traffic commenced. So I could not use these streams to implement a progress bar. – glidester Oct 26 '15 at 10:30