简体   繁体   English

在Spring MVC中使用不带Form的Multipart

[英]Using Multipart without Form in Spring MVC

I had gone through many articles in stackoverflow on this specific topic, after a detailed analysis I have finally dared to post another question on the same topic. 我在stackoverflow中经历了很多关于这个特定主题的文章,经过详细分析后我终于敢于就同一主题发表另一个问题了。

I think this would be obvious that what I wanted to do here, 我想这就是我想在这里做的事情,

What do I want? 我想要什么?

I want to upload a file. 我想上传一个文件。 I am using angularjs and Spring MVC. 我正在使用angularjs和Spring MVC。

Source : 资源 :

Controller @Spring : 控制器@Spring:

@RequestMapping(value="/upload", method=RequestMethod.POST, consumes = {"multipart/form-data"})
public String handleFileUpload(@RequestParam(value = "file") MultipartFile file){
    String name="";
    if (!file.isEmpty()) {
        try {
            byte[] bytes = file.getBytes();
            BufferedOutputStream stream =
                    new BufferedOutputStream(new FileOutputStream(new File(name)));
            stream.write(bytes);
            stream.close();
            return "You successfully uploaded " + name + "!";
        } catch (Exception e) {
            return "You failed to upload " + name + " => " + e.getMessage();
        }
    } else {
        return "You failed to upload " + name + " because the file was empty.";
    }
}
@Bean
    public MultipartResolver multipartResolver() {
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
        multipartResolver.setMaxUploadSize(500000000);
        return multipartResolver;
    }

HTML : HTML:

File to upload: <input type="file"
            file-model="file" name="fd"><br /> Name: <input type="text" name="name"><br />
        <br /> <input type="submit" ng-click="uploadFile()" value="Upload"> Press here to
        upload the file!

JS : JS:

$scope.uploadFile = function() {
    var fd = new FormData();
    var file = $scope.file;
    fd.append('file', file);
    $http.post("/upload",fd,
            {
                headers : {
                    'Content-Type' : undefined
                }
            }).success(function(data) {
        debugger;
    }).error(function(data) {
        debugger;
    })
}

Looks fair??? 看起来很公??? Here are the observations 以下是观察结果

Observations on execution: 执行情况观察:

在此输入图像描述

在此输入图像描述

References : 参考文献:

Spring MVC - AngularJS - File Upload - org.apache.commons.fileupload.FileUploadException Spring MVC - AngularJS - 文件上传 - org.apache.commons.fileupload.FileUploadException

Javascript: Uploading a file... without a file Javascript:上传文件...没有文件

What is the boundary parameter in an HTTP multi-part (POST) Request? HTTP多部分(POST)请求中的边界参数是什么?

And many more....:) 还有很多....:)


Update 更新

Directive which is used in angular, 用于角度的指令,

myApp.directive("fileread", [function () {
    return {
        scope: {
            fileread: "="
        },
        link: function (scope, element, attributes) {
            element.bind("change", function (changeEvent) {
                var reader = new FileReader();
                reader.onload = function (loadEvent) {
                    scope.$apply(function () {
                        scope.fileread = loadEvent.target.result;
                    });
                }
                reader.readAsDataURL(changeEvent.target.files[0]);
            });
        }
    }
}]);

Request extracted from chrome : 从chrome中提取的请求:

在此输入图像描述

Problem in my approach : 我的方法有问题:

I created a bean for MultiPartResolver. 我为MultiPartResolver创建了一个bean。 My understanding after resolving the issue is like you define this bean only when you want a specific type of file or something very specific to the application. 解决问题后我的理解就像你只想在特定类型的文件或特定于应用程序的东西时定义这个bean。 Although I seek more insight into this and would love to hear from techies of stackoverflow. 虽然我寻求更深入的了解这一点,并希望听到stackoverflow技术人员的意见。

Solution for current problem: 当前问题的解决方案:

I would give my source code, 我会给出我的源代码,

HTML : HTML:

<div ng-controller="myCtrl">
        <input type="file" file-model="myFile" />
        <button ng-click="uploadFile()">upload me</button>
    </div>

AngularJS : AngularJS:

     var myApp = angular.module('myApp', []);

        myApp.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]);
                        });
                    });
                }
            };
        }]);
        myApp.controller('myCtrl', ['$scope', '$http', function($scope, $http){

            $scope.uploadFile = function(){
                var file = $scope.myFile;
                var fd = new FormData();
                fd.append('file', file);
    //We can send anything in name parameter, 
//it is hard coded to abc as it is irrelavant in this case.
                var uploadUrl = "/upload?name=abc";
                $http.post(uploadUrl, fd, {
                    transformRequest: angular.identity,
                    headers: {'Content-Type': undefined}
                })
                .success(function(){
                })
                .error(function(){
                });
            }

        }]);

Spring : 春天:

@RequestMapping(value="/upload", method=RequestMethod.POST)
    public String handleFileUpload(@RequestParam("name") String name,
            @RequestParam("file") MultipartFile file){
        if (!file.isEmpty()) {
            try {
                byte[] bytes = file.getBytes();
                BufferedOutputStream stream =
                        new BufferedOutputStream(new FileOutputStream(new File(name)));
                stream.write(bytes);
                stream.close();
                return "You successfully uploaded " + name + "!";
            } catch (Exception e) {
                return "You failed to upload " + name + " => " + e.getMessage();
            }
        } else {
            return "You failed to upload " + name + " because the file was empty.";
        }
    }

And @arahant Even though we don't see any document base64 content in the request payload while sending request, angular does send MultiPartFile, here is the screenshot 和@arahant即使我们在发送请求时没有在请求有效负载中看到任何文档base64内容,angular也会发送MultiPartFile,这里是截图

在此输入图像描述

Thanks to all the references. 感谢所有参考。 If not for these people I wouldn't have solved this problem at all. 如果不是这些人,我根本不会解决这个问题。

References : 参考文献:

http://uncorkedstudios.com/blog/multipartformdata-file-upload-with-angularjs http://uncorkedstudios.com/blog/multipartformdata-file-upload-with-angularjs

Using MultipartHttpServletRequest would be a simple option here, which should work without any other change. 在这里使用MultipartHttpServletRequest是一个简单的选项,它可以在没有任何其他更改的情况下工作。

public String handleFileUpload(MultipartHttpServletRequest request) {
    Map<String, MultipartFile> uploadedFiles = request.getFileMap();
    //...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM