Java 400(错误请求)错误-使用JQuery AJAX上载Spring启动文件
我正在尝试使用thymeleaf ajax和spring boot上传图片。我已经使用了在stackoverflow和其他论坛上找到的大部分帖子,但我似乎确实在工作。我已经在我的安全配置中添加了CSRF,并将其包含在ajax上传脚本中,但仍然面临“400(错误请求)”错误 异常错误Java 400(错误请求)错误-使用JQuery AJAX上载Spring启动文件,java,ajax,spring,spring-security,jquery-file-upload,Java,Ajax,Spring,Spring Security,Jquery File Upload,我正在尝试使用thymeleaf ajax和spring boot上传图片。我已经使用了在stackoverflow和其他论坛上找到的大部分帖子,但我似乎确实在工作。我已经在我的安全配置中添加了CSRF,并将其包含在ajax上传脚本中,但仍然面临“400(错误请求)”错误 异常错误 017-03-01 23:50:06.893 ERROR 58753 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.
017-03-01 23:50:06.893 ERROR 58753 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is org.apache.commons.fileupload.FileUploadException: Stream closed] with root cause
java.io.IOException: Stream closed
at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:372) ~[tomcat-embed-core-8.0.30.jar:8.0.30]
at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:190) ~[tomcat-embed-core-8.0.30.jar:8.0.30]
at java.io.FilterInputStream.read(FilterInputStream.java:133) ~[na:1.8.0_65]
at org.apache.commons.fileupload.util.LimitedInputStream.read(LimitedInputStream.java:134) ~[commons-fileupload-1.3.2.jar:1.3.2]
at org.apache.commons.fileupload.MultipartStream$ItemInputStream.makeAvailable(MultipartStream.java:999) ~[commons-fileupload-1.3.2.jar:1.3.2]
at org.apache.commons.fileupload.MultipartStream$ItemInputStream.read(MultipartStream.java:903) ~[commons-fileupload-1.3.2.jar:1.3.2]
at java.io.InputStream.read(InputStream.java:101) ~[na:1.8.0_65]
at org.apache.commons.fileupload.util.Streams.copy(Streams.java:100) ~[commons-fileupload-1.3.2.jar:1.3.2]
at org.apache.commons.fileupload.util.Streams.copy(Streams.java:70) ~[commons-fileupload-1.3.2.jar:1.3.2]
at org.apache.commons.fileupload.MultipartStream.readBodyData(MultipartStream.java:593) ~[commons-fileupload-1.3.2.jar:1.3.2]
上传
<form id="upload-file-input" th:action="@{/uploadFile}" method="post" th:object="${picture}" enctype="multipart/form-data" class="form-inline inline new-item">
<div th:replace="common/layout :: flash"></div>
<fieldset>
<legend> Upload Picture</legend>
<div class="row">
<div class="col s12 l8">
<div class="file-wrapper">
<input type="file" id="file" name="uploadfile"/>
<span class="placeholder" data-placeholder="Choose an image...">Choose an image...</span>
<label for="file" class="button">Browse</label>
<span id="upload-file-message"></span>
</div>
</div>
<button type="submit" class="btn btn-primary">Upload</button>
</div>
</fieldset>
<div class="style16"></div>
</form>
Upload.js
var token = $("meta[name='_csrf']").attr("content");
$.ajaxSetup({
beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRF-TOKEN', token);
}
});
var $form = $("#upload-file-input");
$form.on("submit", function(e){
e.preventDefault();
$.ajax({
url: $form.prop('action'),
type: "POST",
data: new FormData($("#upload-file-input")[0]),
enctype: 'multipart/form-data',
processData: false,
contentType: false,
cache: false,
success: function () {
// Handle upload success
$("#upload-file-message").text("File succesfully uploaded");
},
error: function () {
// Handle upload error
$("#upload-file-message").text("File not uploaded (perhaps it's too much big)");
}
});
});
您的错误的根本原因似乎是 嵌套异常为org.springframework.web.multipart.MultipartException:无法分析多部分servlet请求 这让我相信您的服务器端工作正常,但客户端没有以预期的格式发送数据 您可以尝试将ajax调用改为以下内容吗
// create a new form
var formData = new FormData();
// add your binary value to the file key
formData.append("file", fileBinary);
$.ajax({dataType : 'json',
...
data : formData, // add the form
...
然后在服务器端,上传的文件对象将出现在文件
参数中
public String uploadFile(@RequestParam("file") MultipartFile uploadfile) {
试着像这样获取表单数据
let uploadFile = $('#upload-file-input')[0];
let formData = new FormData(uploadFile);
在
ajax
data
属性中发送此表单数据。问题的原因是java.io.IOException:Stream closed
。这很可能意味着在多部分请求解析开始之前,某些代码已经在HttpServletRequest
的InputStream
上调用了close()
一个可能的罪魁祸首可能是servletFilter
的一个有缺陷的实现,该实现使用缓存装饰器(除了多部分处理之外,它在大多数操作中使用缓存的请求内容)包装请求,并在将修饰的请求传递给进一步处理之前关闭输入流
通过调试查看HttpServletRequest
的InputStream
上的close
调用,应该可以发现罪魁祸首
如果由于某种原因,这很困难,您也可以尝试禁用任何第三方筛选器(各种验证、日志记录、监视筛选器等),看看问题是否仍然存在。您是否遇到过异常?@MattClark Yes ido@MattClark抛出IOExceptionI将值添加到formData.append(“file”,$('input[type=“file”]”)中[0]).val();但是得到一个错误rg.springframework.web.multipart.MultipartException:当前请求不是一个多部分请求-
let uploadFile = $('#upload-file-input')[0];
let formData = new FormData(uploadFile);