1

I added flow.js in my proyect following the instructions and the call to my java servlet:

localhost:8080/WebExample/UploadImgServlet?flowChunkNumber=1&flowChunkSize=1048576&flowCurrentChunkSize=693916&flowTotalSize=693916&flowIdentifier=693916-image2png&flowFilename=image2.png&flowRelativePath=image2.png&flowTotalChunks=1`

In my servlet I get all parameters of the url (flowChuckNumber, flowChuckSize, etc) but when I try to get the file (request.getInputStream()), it's empty and upload 0 bytes.

Where is the problem? Any Idea?

I found a similar question but it was with PHP...

My code:

HTML(the image is displayed):

...
...
<div flow-init="{singleFile:true}"
 flow-file-added="!!{png:1,gif:1,jpg:1,jpeg:1}[$file.getExtension()]"
     flow-files-submitted="$flow.upload()"
     flow-file-success="$file.msg = $message">
         <div class="drop" flow-drop ng-class="dropClass">

        <md-button class="md-raised md-primary" type="file" flow-btn>Upload Image</md-button>
    <b>OR</b>
    Drag And Drop your image here
  </div>
    <div class="thumbnail" ng-show="!$flow.files.length">
      <img src="http://www.placehold.it/200x150/EFEFEF/AAAAAA&text=no+image" alt="Image"/>
    </div>
    <div class="thumbnail" ng-show="$flow.files.length">
      <img flow-img="$flow.files[0]" />
    </div>

  <table>
    <tr ng-repeat="file in $flow.files">
        <td>{{$index+1}}</td>
        <td>{{file.name}}</td>
        <td>{{file.msg}}</td>
    </tr>
  </table>
</div>
...
...

App AngularJs:

var app = angular.module("webexample", ['ngMaterial', 'ngNotify','uiGmapgoogle-maps','flow'])
.config(['flowFactoryProvider', function (flowFactoryProvider) {
      flowFactoryProvider.defaults = {
        target: '/WebExample/UploadImgServlet',
        permanentErrors: [404, 500, 501],
        maxChunkRetries: 1,
        chunkRetryInterval: 5000,
        simultaneousUploads: 1
      };
      flowFactoryProvider.on('catchAll', function (event) {
        console.log('catchAll', arguments);
      });
      // Can be used with different implementations of Flow.js
      // flowFactoryProvider.factory = fustyFlowFactory;
    }])
    .directive('appDownloadUrl', [function () {
      return {
        restrict: 'A',
        link: function(scope, element, attrs) {
          element.bind('dragstart', function (event) {
            var config = scope.$eval(attrs.appDownloadUrl);
            if (!config.disabled) {
              var data = config.mime + ':' + config.name + ':' + window.location.href + config.url;
                        console.log("data: "+data);
              event.dataTransfer.setData('DownloadURL', data);
            }
          });
        }
      };
    }])
    .directive("appDragstart", [function () {
      return function(scope, element, attrs) {
        element.bind('dragstart', function (event) {
          scope.$eval(attrs.appDragstart);
        });
      }
    }]).directive("appDragend", [function () {
      return function(scope, element, attrs) {
        element.bind('dragend', function (event) {
          scope.$eval(attrs.appDragend);
        });
      }
    }]).run(function ($rootScope) {
      $rootScope.dropEnabled = true;
    });

My Servlet (I followed this example):

protected void doService(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException
    {
        LOGGER.debug("[UploadImgServlet - doService] - init");

        int resumableChunkNumber  = getResumableChunkNumber(request);

        ResumableInfo info = getResumableInfo(request);
        //info contains all flow parameters of the url.

        RandomAccessFile raf = new RandomAccessFile(info.resumableFilePath, "rw");

        //Seek to position
        raf.seek((resumableChunkNumber - 1) * info.resumableChunkSize);

        //Save to file
        InputStream is = request.getInputStream();
        long readed = 0;

        long content_length = request.getContentLength();
        //**PROBLEM: request.getContentLength return -1 so read 0 bytes**


        byte[] bytes = new byte[1024 * 100];
        while(readed < content_length) {
            int r = is.read(bytes);
            if (r < 0)  {
                break;
            }
            raf.write(bytes, 0, r);
            readed += r;
        }
        raf.close();
...
...

3 Answers 3

2

The input stream will be empty because flowjs posts the content using MultiPart by default. The author of the Java code specified that "Octet" should be used for uploads, not multi-part.

UploadServlet accepts Resumable.js Upload with 'octet'

You need to add "method:octet" to your init,

<div flow-init="{singleFile:true, method:octet}"

I am using Spring, so I just used MultipartHttpServletRequest to get the posted data with MultiPart instead because MultiPart is more common.

This is how I received the contents of the file:

Iterator<String> itr = request.getFileNames();

/* Iterate each file, there should only be one/one chunk */
while (itr.hasNext()) {
    fileUploaded = request.getFile(itr.next());
    raf.write(fileUploaded.getBytes());
}

raf.close();

I had to do more fixes to the java code provided because it was estimating the number of chunks to receive wrong, so I just used the "flowTotalChunks" parameter.

Sign up to request clarification or add additional context in comments.

Comments

0

You don't need to worry about content length. The HttpServletRequest will terminate the input stream at the correct point. Just read until end of stream.

4 Comments

if try "while ((read = uploadedInputStream.read(bytes)) != -1)" the result is the same, the first reading is -1 so upload 0 bytes.
Then nothing was sent.
I know it but I want to know why the file is not sent with Flowjs and how fix it. I found this: stackoverflow.com/questions/25740110/… but the result is the same, the file is not sent.
Have you tried a different browser? after checking mine, it does receive data, but there are other problems you will run into even when you receive some input because the Java code isn't completely up to date with the Javascript side.
0

I wanted a lib to upload images with more options and visually appealing (drop file from a folder, thumbnail, etc) than the default html input and I have not been able to do with Flowjs and Java Servlet, so I looked for another lib:

https://github.com/danialfarid/ng-file-upload

https://angular-file-upload.appspot.com/

With this lib, I found it easy to use with Java Servlet.

I don't mark this post as solved for if someone finds a way to do it with Flowjs.

3 Comments

I thought flow.js is working very well with angular, so I also attempted to use and got the same problem as you did. The problem seems to be in the Java code, it seems to be out of date and does not look at currentChunkSize, and ends up thinking it didn't receive all the chunks. I will try to fix it and let you know.
@user1384975 I found the other lib that I said and it works fine so I forgot Flowjs although Flowjs is a bit more complete. If you find the solution with Flowjs, let me know please.
solution found, I've posted it. You need to set upload type of octet, or handle multi-part post if not.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.