4

I'm trying to upload (actually POST) numerous small files in one go along with some key, value pairs:

                $scope.uploadFiles = function(files) {

                    if (files.length === 0) {
                        return;
                    }

                    var formData = new FormData();
                    formData.append('keyName1', 'keyValue1');
                    formData.append('keyName2', 'keyValue2');
                    formData.append('keyName3', 'keyValue3');
                    for (var i = 0; i < files.length; i++) {
                        formData.append('files[]', files[i]);
                    }

                    $http.post( '/myEndpoint', formData, {
                        headers: { 'Content-Type': undefined },
                        transformRequest: angular.identity
                    }).success(function (result) {
                        console.log('YAY');
                    }).error(function () {
                        console.log('NAY');
                    });                 
                }

Here's the Java backend:

@RequestMapping(value = "/myEndpoint", method = RequestMethod.POST)
@ResponseBody
public void uploadFiles(
        @RequestParam("files") List<MultipartFile> fileList,
        @RequestParam("keyName1") String keyName1,
        @RequestParam("keyName2") String keyName2,
        @RequestParam("keyName3") String keyName3,
        HttpServletResponse response, HttpSession session) throws Exception {

    log.debug(fileList.size()); // Always logs zero
}

The endpoint is being hit but the filesList length is zero. I've also changed

    List<MultipartFile> fileList to MultipartFile[] filesArray

but that didn't work wither.

Can anyone shed some light please?

Cheers,

Paul

2
  • for (var i = 0; i < files.length; i++) { formData.append('files[]', files[i]); } What is the purpose of this? Commented Nov 25, 2015 at 16:18
  • Hi, the purpose is to append an array to FormData where the array contains n files. [link] (developer.mozilla.org/en-US/docs/Web/API/FormData/append) Commented Nov 25, 2015 at 17:31

2 Answers 2

6

This might be helpful to you.

Angular:

$scope.uploadFiles = function(files) {
    if (files.length === 0) {
        return;
    }

    var formData = new FormData();
    formData.append('keyName1', 'keyValue1');
    formData.append('keyName2', 'keyValue2');
    formData.append('keyName3', 'keyValue3');
    for (var i = 0; i < files.length; i++) {
        formData.append('file'+i, files[i]);
    }

    $http.post( '/myEndpoint', formData, {
        headers: { 'Content-Type': undefined },
        transformRequest: angular.identity
    }).success(function (result) {
        console.log('YAY');
    }).error(function () {
        console.log('NAY');
    });                 
}

On Spring/Java Side:

RequestMapping(value = "/myEndpoint", method = RequestMethod.POST)
public @ResponseBody Object uploadFiles(MultipartHttpServletRequest request, HttpServletResponse response) throws IOException {
    //do stuff here...
    final String keyName1= request.getParameter('keyName1');
    //and so on......

    Iterator<String> iterator = request.getFileNames();
    MultipartFile multipartFile = null;
    while (iterator.hasNext()) {
        multipartFile = request.getFile(iterator.next());
        //do something with the file.....
    }
}

BTW, on you angular side, you can always end the file on one go or with multiple request. It's up to you how you want that implemented.

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

3 Comments

Thanks, I'll give this a bash.
"Thanks, that worked nicely" - in which case, please accept the answer, in order to help others in future.
Rossi, if you repost this answer to my question I will accept it. I used Vue + vue-resource, so maybe your answer will help more people.
0

I used a library on GitHub to help me accomplish this task with my Java Glassfish Server.

https://github.com/nervgh/angular-file-upload

I only needed to upload a single file, and here is the Java Backend to receive that file. This framework does have support to upload multiple files to the server.

@POST
@Path("/Endpoint")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response whateverEndPoint(@FormDataParam("fileName") InputStream fileInputStream,
        @FormDataParam("fileName") FormDataContentDisposition contentDispositionHeader,
        @FormDataParam("additionalParameter") String additionalParameter) {

    System.out.println(contentDispositionHeader.getFileName());

    String output = "File Received on the server: ";

    return Response.status(200).entity(output).build();

}

Here is my angular controller that uses the framework:

angular.module('AppThing').controller('DemoController',function($rootScope,$scope,FileUploader){

//creating the uploader with the correct url
$scope.uploader = new FileUploader({
    url : 'Endpoint',
    method : 'POST',
    alias: 'fileName',
    autoUpload:true
});

//runs right after we add a file to the queue
$scope.uploader.onAfterAddingFile = function(item){
};

//runs right before we upload an item to the server
$scope.uploader.onBeforeUploadItem = function(item){
        console.log('This is just before the image upload');
        item.formData.push({'additionalParameter':  $rootScope.additionalParameter});
};

$scope.uploader.onSuccessItem = function(item, response, status, headers) {

};



});

Hope this helps

1 Comment

Hi, thanks for your post it's much appreciated. I've gone with Rossi Robinsion post as I do not want to use a JS library and preferred the Java MultipartHttpServletRequest approach. Once again thanks.

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.