Spring MVC - AngularJS - File Upload - org.apache.commons.fileupload.FileUploadException

前端 未结 4 1172
情书的邮戳
情书的邮戳 2020-11-30 02:11

I have a Java Spring MVC Web application as server. And AngularJS based application as client.

In AngularJS, I have to upload a file and send to server.

Here

4条回答
  •  情话喂你
    2020-11-30 02:36

    Carlos Verdes's answer failed to work with my $http interceptor, which adds authorization headers and so on. So I decided to add to his solution and create mine using $http.

    Clientside Angular (1.3.15)

    My form (using the controllerAs syntax) is assuming a file and a simple object containing the information we need to send to the server. In this case I'm using a simple name and type String property.

    The first step was to create a directive that binds my file to the scope of the designated controller (in this case myController) so I can access it. Binding it directly to a model in your controller won't work as the input type=file isn't a built-in feature.

    .directive('fileModel', ['$parse', function ($parse) {
        return {
            restrict: 'A',
            link: function(scope, element, attrs) {
                var model = $parse(attrs.fileModel);
                var modelSetter = model.assign;
    
                element.bind('change', function(){
                    scope.$apply(function(){
                        modelSetter(scope, element[0].files[0]);
                    });
                });
            }
        };
    }]);
    

    Secondly I created a factory called myObject with an instance method create that allows me to transform the data upon invoking create on the server. This method adds everything to a FormData object and converts it using the transformRequest method (angular.identity). It is crucial to set your header to undefined. (Older Angular versions might require something than undefined to be set). This will allow the multidata/boundary marker to be set automatically (see Carlos's post).

      myObject.prototype.create = function(myObject, file) {
            var formData = new FormData();
            formData.append('refTemplateDTO', angular.toJson(myObject));
            formData.append('file', file);
    
            return $http.post(url, formData, {
                transformRequest: angular.identity,
                headers: {'Content-Type': undefined }
            });
    }
    

    All that is left to do client side is instantiating a new myObject in myController and invoking the create method in the controller's create function upon submitting my form.

    this.myObject = new myObject();
    
    this.create = function() {
            //Some pre handling/verification
            this.myObject.create(this.myObject, this.file).then(
                                  //Do some post success/error handling
                                );
        }.bind(this);
    

    Serverside Spring (4.0)

    On the RestController I can now simply do the following: (Assuming we have a POJO MyObject)

    @RequestMapping(method = RequestMethod.POST)
    @Secured({ "ROLE_ADMIN" }) //This is why I needed my $httpInterceptor
    public void create(MyObject myObject, MultipartFile file) {
         //delegation to the correct service
    }
    

    Notice, I'm not using requestparameters but just letting spring do the JSON to POJO/DTO conversion. Make sure you got the MultiPartResolver bean set up correctly too and added to your pom.xml. (And Jackson-Mapper if needed)

    spring-context.xml

    
         
    
    

    pom.xml

    
            commons-fileupload
            commons-fileupload
            ${commons-fileupload.version} 
    
    

提交回复
热议问题