我有一个正常工作的文件上传表单,除非我发送的文件大于我在Spring中配置的文件。
我之前在使用Spring编写的另一个应用程序中使用了相同的代码,不同之处在于我使用的是ExtJs 4.2,现在使用的是ExtJs 6.0。老应用程序也使用了Spring security 3,新的4。
Spring端已配置为阻止超过3MB的文件。
来自WebMvcConfig.java:
@Bean(name="multipartResolver")
public CommonsMultipartResolver commonsMultipartResolver()
{
ToolkitCommonsMultipartResolver resolver = new ToolkitCommonsMultipartResolver();
resolver.setMaxUploadSize(Constants.UPLOAD_MAX_FILE_SIZE);
return resolver;
}
来自ToolkitCommonsMultipartResolver:
public class ToolkitCommonsMultipartResolver extends CommonsMultipartResolver {
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
protected MultipartParsingResult parseRequest(final HttpServletRequest request) {
String encoding = determineEncoding(request);
FileUpload fileUpload = prepareFileUpload(encoding);
List fileItems;
try {
fileItems = ((ServletFileUpload) fileUpload).parseRequest(request);
}
catch (FileUploadBase.SizeLimitExceededException ex) {
System.out.println("******* MultipartParsingResult limit exceeded");
request.setAttribute("fileSizeExceeded", ex);
fileItems = Collections.EMPTY_LIST;
}
catch (FileUploadException ex) {
throw new MultipartException("Could not parse multipart servlet request", ex);
}
return parseFileItems(fileItems, encoding);
}
}
我的自定义控制器:
@PreAuthorize("hasAuthority('ACTIVITY_CREATE_UPDATE')")
@RequestMapping(value = "/activity/editActivity", method = RequestMethod.POST, consumes="multipart/form-data", produces=MediaType.TEXT_HTML_VALUE )
public @ResponseBody String editActivity(@Valid ActivityBean bean, BindingResult result, HttpServletRequest request) {
//WebMvcConfig.commonsMultipartResolver will throw exception if file size exceeds the max size
//Passed as a request attribute
Object exception = request.getAttribute("fileSizeExceeded");
if (exception != null && FileUploadBase.SizeLimitExceededException.class.equals(exception.getClass()))
{
log.info("File too large");
String msg = "The file you sent has exceeded the maximum upload size of " + (Constants.UPLOAD_MAX_FILE_SIZE / 1000000L) + " MB.";
return "{\"success\" : false, \"msg\" : \"" + msg + "\"}";
}
...other code to process request
}
}
Spring security http标签具有以下代码,允许从服务器显示帧内容(X-Frame-Options)。在我添加此代码之前,所有响应都被阻止(保存成功与否):
<headers>
<frame-options policy="SAMEORIGIN"/>
</headers>
Spring将返回成功:false,我在控制器中设置了消息。在chrome中,我看到连接中止(net :: ERR_CONNECTION_ABORTED)。在ExtJs代码深处,我找到了onComplete方法:
/**
* Callback handler for the upload function. After we've submitted the form via the
* iframe this creates a bogus response object to simulate an XHR and populates its
* responseText from the now-loaded iframe's document body (or a textarea inside the
* body). We then clean up by removing the iframe.
* @private
*/
onComplete: function()
在onComplete()内部,上传后有一个电话
doc = me.getDoc();
此方法尝试访问iFrame中阻止从服务器返回的内容。在这种情况下,似乎Spring安全标头不起作用。有一个问题(e)抛出错误:
未捕获DOMException:阻止原始“http://localhost:8080”的帧访问跨源帧。(...)
有谁知道如何解决此问题?我可以禁用Muitipart解析器并接受完整的文件,并在我的自定义代码中进行大小验证。如果超过大小,则首先阻止文件上载更有意义。这是Spring security 4还是ExtJs6问题?