在 Spring MVC 中使用不带表单的多部分

Using Multipart without Form in Spring MVC

我在 Whosebug 上看了很多关于这个特定主题的文章,在详细分析之后我终于敢 post 另一个关于同一主题的问题。

我认为这很明显就是我想在这里做的事情,

我想要什么?

我要上传文件。我正在使用 angularjs 和 Spring MVC。

来源:

控制器@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 :

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 :

$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;
    })
}

看起来很漂亮???以下是观察结果

对执行的观察:

参考文献:

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

Javascript: Uploading a file... without a file

还有更多......:)


更新

在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]);
            });
        }
    }
}]);

从chrome提取的请求:

在这里使用 MultipartHttpServletRequest 是一个简单的选项,无需任何其他更改即可工作。

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

我的方法有问题:

我为 MultiPartResolver 创建了一个 bean。解决问题后我的理解就像您仅在需要特定类型的文件或特定于应用程序的文件时才定义此 bean。尽管我希望对此有更多的了解,并且很想听听 Whosebug 技术人员的意见。

当前问题的解决方案:

我会给出我的源代码,

HTML :

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

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.";
        }
    }

和@arahant 尽管我们在发送请求时没有在请求负载中看到任何文档 base64 内容,angular 确实发送了 MultiPartFile,这是屏幕截图

感谢所有参考资料。如果不是这些人,我根本不会解决这个问题。

参考资料:

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