本文介绍了Spring启动文件上传错误请求400的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我已经读过spring引导应该自动配置的当mvc依赖关系存在时,分段上传本身。 来自: https://spring.io/guides/gs/uploading-files/作为自动配置Spring MVC的一部分,Spring Boot将会创建一个MultipartConfigElement bean,并为自己的文件上传做好准备。 发送请求的Javascript函数: var postFormData = function(file,url,successCallback,errorCallback,progressCallback){ var xhr = new XMLHttpRequest(),$ b $ formData = new FormData(); formData.append(file,file); xhr.onreadystatechange = function(){ if(xhr.readyState === 4){ if(xhr.status === 200){ successCallback(xhr.status); // File is Uploaded } else { errorCallback(xhr.status); } } }; 函数progress(evt){ if(evt.lengthComputable){ var percentComplete = evt.loaded / evt.total; progressCallback(percentComplete); } else { progressCallback(evt.loaded); } } xhr.open(POST,url,true); //xhr.setRequestHeader(\"Content-Type,multipart / form-data); xhr.addEventListener(progress,progress,false); xhr.send(formData); $ b $ p $ b $ p $多元配置Bean在我的主应用程序类中: @Bean MultipartConfigElement multipartConfigElement(){ MultipartConfigFactory factory = new MultipartConfigFactory(); factory.setMaxFileSize(MAXIMUM_FILE_SIZE); factory.setMaxRequestSize(MAXIMUM_FILE_SIZE); return factory.createMultipartConfig(); $ b $上传控制器 @Controller @RequestMapping(/ api) public class FileUploadController { $ b $ @Autowired UserRepository userRepository; @Autowired VolumeMetaRepository volumeMetaRepository; $ b $ ** 处理文件上传volumedata * * @param文件不能为空 ** / @ RequestMapping(value =/ volumedata / meta / test,consumes =multipart / form-data,method = RequestMethod.POST) @ResponseBody public void handleFileUpload( @RequestParam file)MultipartFile file){ if(!file.isEmpty()){ / * try { InputStream fileStream = file.getInputStream(); OutputStream out = new FileOutputStream(file.getOriginalFilename()); IOUtils.copy(fileStream,out); catch(IOException e){ throw new IllegalStateException(Error uploadloading。,e); } * / / * String filePath = request.getServletContext()。getRealPath(/); 尝试{ file.transferTo(new File(filePath +/+ file.getOriginalFilename())); } catch(IOException e){ e.printStackTrace(); code $ $ b $因为有其他Stackoverflow线程是一个新的Spring启动版本解决了我使用'1.2.2.BUILD-SNAPSHOT',我的gradle依赖关系的问题: $ b $ version ='1.2.2.BUILD-SNAPSHOT'依赖关系{编译组:'org.springframework.boot',名称:'spring-boot-starter-web',版本:version 编译组:'org.springframework.boot',名称:'spring-boot-starter-aop',版本:version 编译组:'org.springframework.boot',名称:'spring-boot编译组:'org.springframework.hateoas',名称:'spring-hateoas',版本:'0.16.0.RELEASE'编译组: 'org.springframework.data',name:'spring-data-rest-webmvc',版本:'2.1.4.RELEASE'编译组:'org.springframework.boot',名称:'spring-boot -starter安全,版本:版本编译组:'org.springframework.boot',名称:'spring-boot-starter-data-rest',版本:版本编译组:'commons-io' :'commons-io',版本:'2.1'编译组:'com.fasterxml.jackson.datatype',名称:'jackson-datatype-jsr310',版本:'2.3.4'编译组:'org.springframework.boot',名称:'spring-boot-starter-integration',版本:version 编译组:'org.springframework.boot',名称:'spring-boot-starter- websocket',版本:编译组:'org.springframework.session',名称:'spring-session',版本:'1.0.0.BUILD-SNAPSHOT'编译组:'org。 springframework.data',name:'spring-data-redis',版本:'1.4.1.RELEASE'编译组:'redis.clients',名称:'jedis',版本:'2.4.2' 编译组:'org.springframework.boot',名称:'spring-boot-starter-remote-shell',版本:版本编译组:'com.google.guava',名称:'guava',版本:'18 .0' 编译文件('lib / vendor / niftijio.jar'); compile(com.h2database:h2) testCompile(group:'org.springframework.boot',name:'spring-boot-starter-test',版本:'1.1.6.RELEASE'){ exclude(module:'commons-logging')} testCompile组:'com.jayway.jsonpath',name :'json-path',version:'0.9.1' testCompile'org.springframework:spring-test:3.2.3.RELEASE' testCompile'junit:junit:4. +' testCompileorg.mockito:mockito-all:1.9.5 引发的错误是: {timestamp:2015-01-19T10:22:53.710Z ,status:400,error:Bad Request,exception:org.springframework.web.bind.MissingServletRequestParameterException,message :所需的MultipartFile参数文件不存在,path:/ api / volumedata / meta / test} pre> 它告诉我,文件 ameter不存在,但我的请求有效载荷显示参数在那里。 请求有效载荷: --- --- WebKitFormBoundary40qPAhpvA20pd8V1 Content-Disposition:form-data; name =file C:\ fakepath\test.gz ------ WebKitFormBoundary40qPAhpvA20pd8V1-- 有人想法我的配置中缺少什么东西,或者是什么原因导致了错误? 前进解决方案我找到了错误的原因。它不是来自我的Spring控制器,而是来自我的angularJS html代码。 $ b $ p这是我的上传输入字段: pre $ < div class =form-group ng-class ={'has-error':volume_upload_form.file_field。$ invalid&& volume_upload_form.file_field 。$脏}> < label name = file-field-label>卷数据集< / label> 名称=文件 ng-model = upload.file 所需 id =文件 file_ext_validation 类型=file extensions =nii,NII,gz,jpeg,JPG/> < div class =error ng-show =volume_upload_form.volume。$ invalid> ng-show =volume_upload_form.volume。$ error.fileExtValidation> 文件必须是.nii< / small> < / div> < / div> 正如你所看到的,使用默认的ng-model也与我的角度控制器(upload是我的Controller别名)。 $ b $ pre $ ng-model = upload.file 但是Angular默认不支持文件输入html字段。所以只有一个包含文件路径的字符串被存储在upload.file中,而不是一个实际的文件对象。我不得不写一个自定义指令: $ $ p $ $ $ $ $ $ $ var fileModel = function($ parse){ return {限制:'A', link:function(scope,element,attrs){ var model = $ parse(attrs.fileModel); var modelSetter = model.assign; $ b element.bind('change',function(){ scope。$ apply(function(){ modelSetter(scope,element [0] .files [0] ); }); }); } }; } module.exports = fileModel; 其中返回实际的File对象。 < div class =form-group ng-class ={'has-error':volume_upload_form.file_field。$ invalid&&& volume_upload_form.file_field。$ dirty}> < label name = file-field-label>卷数据集< / label> file-model =upload.fileModel ng-model =file required file_ext_validation type = file extensions =nii,NII,gz,jpeg,JPG/> < div class =error ng-show =volume_upload_form.volume。$ invalid> ng-show =volume_upload_form.volume。$ error.fileExtValidation> 文件必须是.nii< / small> < / div> < / div> 您可以看到 $ pre>文件模型=upload.fileModel 文件输入字段到角度控制器。 这里是正确的请求有效载荷。 ------ WebKitFormBoundaryR1AXAwLepSUKJB3i 内容处置:形式数据; NAME = 文件; filename =test.nii.gz Content-Type:application / x-gzip ------ WebKitFormBoundaryR1AXAwLepSUKJB3i-- Hello im writing an Webapplication using Spring Boot and AngularJs and need an simple file upload which is not working at the moment.I already read that spring boot should autoconfigure the multipart upload itself when the mvc dependency is present.From :https://spring.io/guides/gs/uploading-files/Javascript Function which sends the Request:var postFormData = function (file, url, successCallback, errorCallback, progressCallback) { var xhr = new XMLHttpRequest(), formData = new FormData(); formData.append("file", file); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { successCallback(xhr.status); //File is Uploaded } else { errorCallback(xhr.status); } } }; function progress(evt) { if (evt.lengthComputable) { var percentComplete = evt.loaded / evt.total; progressCallback(percentComplete); } else { progressCallback(evt.loaded); } } xhr.open("POST", url, true); //xhr.setRequestHeader("Content-Type", "multipart/form-data"); xhr.addEventListener("progress", progress, false); xhr.send(formData);}Multipart configuration Bean in my main app class: @Bean MultipartConfigElement multipartConfigElement() { MultipartConfigFactory factory = new MultipartConfigFactory(); factory.setMaxFileSize(MAXIMUM_FILE_SIZE); factory.setMaxRequestSize(MAXIMUM_FILE_SIZE); return factory.createMultipartConfig(); }Upload Controller:@Controller@RequestMapping("/api")public class FileUploadController { @Autowired UserRepository userRepository; @Autowired VolumeMetaRepository volumeMetaRepository; /** * Handles File upload of volumedata * * @param file Must not be null **/ @RequestMapping(value = "/volumedata/meta/test", consumes= "multipart/form-data", method=RequestMethod.POST) @ResponseBody public void handleFileUpload( @RequestParam("file") MultipartFile file) { if (!file.isEmpty()) { /* try { InputStream fileStream = file.getInputStream(); OutputStream out = new FileOutputStream(file.getOriginalFilename()); IOUtils.copy(fileStream, out); } catch (IOException e) { throw new IllegalStateException("Error uploading file.", e); }*//* String filePath = request.getServletContext().getRealPath("/"); try { file.transferTo(new File(filePath+ "/" + file.getOriginalFilename())); } catch (IOException e) { e.printStackTrace(); }*/ } }And because there are other Stackoverflow Threads were a new Spring boot Version solved the issue Im using '1.2.2.BUILD-SNAPSHOT', my gradle dependencies:version = '1.2.2.BUILD-SNAPSHOT'dependencies { compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version:version compile group: 'org.springframework.boot', name: 'spring-boot-starter-aop', version:version compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version:version compile group: 'org.springframework.hateoas', name: 'spring-hateoas', version:'0.16.0.RELEASE' compile group: 'org.springframework.data', name: 'spring-data-rest-webmvc', version:'2.1.4.RELEASE' compile group: 'org.springframework.boot', name: 'spring-boot-starter-security', version:version compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-rest', version:version compile group: 'commons-io', name: 'commons-io', version:'2.1' compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version:'2.3.4' compile group: 'org.springframework.boot', name: 'spring-boot-starter-integration', version:version compile group: 'org.springframework.boot', name: 'spring-boot-starter-websocket', version:version compile group: 'org.springframework.session', name: 'spring-session', version:'1.0.0.BUILD-SNAPSHOT' compile group: 'org.springframework.data', name: 'spring-data-redis', version:'1.4.1.RELEASE' compile group: 'redis.clients', name: 'jedis', version:'2.4.2' compile group: 'org.springframework.boot', name: 'spring-boot-starter-remote-shell', version:version compile group:'com.google.guava', name:'guava', version:'18.0' compile files ('lib/vendor/niftijio.jar'); compile("com.h2database:h2") testCompile(group: 'org.springframework.boot', name: 'spring-boot-starter-test', version:'1.1.6.RELEASE') { exclude(module: 'commons-logging') } testCompile group: 'com.jayway.jsonpath', name: 'json-path', version:'0.9.1' testCompile 'org.springframework:spring-test:3.2.3.RELEASE' testCompile 'junit:junit:4.+' testCompile "org.mockito:mockito-all:1.9.5"}The thrown error is:{ "timestamp" : "2015-01-19T10:22:53.710Z", "status" : 400, "error" : "Bad Request", "exception" : "org.springframework.web.bind.MissingServletRequestParameterException", "message" : "Required MultipartFile parameter 'file' is not present", "path" : "/api/volumedata/meta/test"}It tells me that the "file" parameter is not present, but my Request payload shows that the parameter is there.Request Payload:------WebKitFormBoundary40qPAhpvA20pd8V1Content-Disposition: form-data; name="file"C:\fakepath\test.gz------WebKitFormBoundary40qPAhpvA20pd8V1--Has somebody an Idea what is missing in my configuration, or what could cause the error ?Thanks in advance 解决方案 I found the reason for the error. It originated not from my Spring controller, but from my angularJS html code.This was my Upload Input field: <div class="form-group" ng-class="{ 'has-error': volume_upload_form.file_field.$invalid && volume_upload_form.file_field.$dirty}"> <label name=file-field-label>Volume Dataset</label> <input value=file name=file ng-model=upload.file required id=file file_ext_validation type="file" extensions="nii,NII,gz,jpeg,JPG"/> <div class="error" ng-show="volume_upload_form.volume.$invalid"> <small class="error" ng-show="volume_upload_form.volume.$error.fileExtValidation"> File must be of type ".nii" </small> </div> </div>As you can see is use the default ng-model too communicate with my angular controller("upload" is my Controller alias).ng-model=upload.fileBut Angular does not support the file input html field by default. So only a string containing the file path was stored in upload.file, NOT an actual File Object. I had to write a custom directive:var fileModel = 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]); }); }); } };}module.exports = fileModel;Which returns the actual File object. My new upload html code was as follows:<div class="form-group" ng-class="{ 'has-error': volume_upload_form.file_field.$invalid && volume_upload_form.file_field.$dirty}"> <label name=file-field-label>Volume Dataset</label> <input name=file file-model="upload.fileModel" ng-model="file" required file_ext_validation type="file" extensions="nii,NII,gz,jpeg,JPG"/> <div class="error" ng-show="volume_upload_form.volume.$invalid"> <small class="error" ng-show="volume_upload_form.volume.$error.fileExtValidation"> File must be of type ".nii" </small> </div> </div>you can see file-model="upload.fileModel"links the File Object from the file input field to the angular controller.Here is the correct Request Payload.------WebKitFormBoundaryR1AXAwLepSUKJB3iContent-Disposition: form-data; name="file"; filename="test.nii.gz"Content-Type: application/x-gzip------WebKitFormBoundaryR1AXAwLepSUKJB3i-- 这篇关于Spring启动文件上传错误请求400的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
09-27 15:42