Undertow/Wildfly Spring 引导时的文件上传和可接受的错误处理
File Upload and acceptable Error Handling on Undertow/Wildfly wth Spring Boot
我们在 Undertow 和 SpringBoot 上有一个项目 运行,正在尝试添加文件上传。第一次尝试成功,文件已通过使用 StandardServletMultipartResolver
绑定到适当的 Bean 并使用 application.properties
配置它。
然而,当涉及到错误处理时,我们 运行 陷入了可怕的困境。
我们通过将标准解析器配置为 100MB 并使用 CommonsMultipartResolver
找到了 "solution"。然后我们添加了一个像这样的过滤器
@Bean
public Filter filter() {
return new OncePerRequestFilter() {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
try {
filterChain.doFilter(request, response);
} catch (ServletException e) {
if (e.getCause()
.getClass()
.equals(org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException.class)) {
int requestSize = request.getContentLength();
Collection<Part> parts = request.getParts();
List<String> oversizedFields = new LinkedList<>();
long uploadSize = 0;
for (Part part : new ArrayList<>(parts)) {
if (uploadSize + part.getSize() > MAX_UPLOAD_SIZE) {
requestSize -= part.getSize();
oversizedFields.add(part.getName());
request.getParameterMap()
.remove(part.getName());
parts.remove(part);
} else {
uploadSize += part.getSize();
}
}
request.setAttribute("oversizedFields", oversizedFields);
SizeModifyingServletRequestWrapper requestWrapper = new SizeModifyingServletRequestWrapper(
request, requestSize, uploadSize);
filterChain.doFilter(requestWrapper, response);
}
}
}
};
}
请求包装器:
private static class SizeModifyingServletRequestWrapper extends
HttpServletRequestWrapper {
private int size;
private long sizeLong;
public SizeModifyingServletRequestWrapper(HttpServletRequest request,
int size, long sizeLong) {
super(request);
this.size = size;
this.sizeLong = sizeLong;
}
@Override
public int getContentLength() {
return size;
}
@Override
public long getContentLengthLong() {
return sizeLong;
}
@Override
public String getHeader(String name) {
if (FileUploadBase.CONTENT_LENGTH.equals(name)) {
return Integer.toString(size);
} else {
return super.getHeader(name);
}
}
}
@Controller
方法然后检查超大文件并将结果添加到 BindingResult
,这很好用,除了文件未绑定到 bean 的事实。
结果是 CommonsMultipartResolver
在尝试解析请求时在 ItemInputStream.makeAvailable()
中抛出一个 MalformedStreamException
,它总是 returns 消息 String ended unexpectedly
.
所以我们回到使用 StandardServletMultipartResolver
,并且能够捕获 RuntimeException
它抛出的很好,但是即使一个文件超过其大小边界,它也绝对不会提供任何表单数据。
我们完全被难住了,因为无论 Resolver 是否惰性工作都没有关系。如果有人对如何解决这个问题有任何进一步的想法,欢迎提出答案=)
更多参考代码:
摘自WebAppInitializer
@Bean(name = "multipartResolver")
public MultipartResolver multipartResolver() {
StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver();
multipartResolver.setResolveLazily(true);
return multipartResolver;
}
@Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
factory.setMaxFileSize("2MB");
factory.setMaxRequestSize("100MB");
return factory.createMultipartConfig();
}
从控制器中提取:
@RequestMapping(method = { RequestMethod.POST, RequestMethod.PUT })
public String saveOrganizationDetails(
@PathVariable(PATH_VARIABLE_ORGANIZATION_ID) String organizationId,
@ModelAttribute @Valid Organization organization,
BindingResult bindingResult, Model model,
RedirectAttributes redirectAttributes, WebRequest request) {
checkForOversizedFiles(request, bindingResult);
Map<String, MultipartFile> files = organization.getStyle().whichFiles();
}
private boolean checkForOversizedFiles(WebRequest request,
BindingResult bindingResult) {
if (request.getAttribute("oversizedFields", WebRequest.SCOPE_REQUEST) instanceof LinkedList) {
@SuppressWarnings("unchecked")
LinkedList<String> oversizedFiles = (LinkedList<String>) request
.getAttribute("oversizedFields", WebRequest.SCOPE_REQUEST);
for (String s : oversizedFiles) {
String errorCode = KEY_ORGANIZATION_LOGO_OVERSIZED_FILE + s;
bindingResult.rejectValue(s,
errorCode);
}
return true;
} else {
return false;
}
}
private void handleUpload(Map<String, MultipartFile> files,
OrganizationStyle style, BindingResult result) {
for (String filename : files.keySet()) {
if (processUpload(files.get(filename), filename)) {
style.setLogoFlag(filename);
} else {
result.reject(KEY_ORGANIZATION_LOGO_UPLOAD_FAILURE);
}
}
}
processUpload()
到目前为止还没有任何功能,这就是我不在此处包含它的原因。
从表单支持 Bean 中提取:
public class OrganizationStyle {
@Transient
private MultipartFile logoPdf;
@Transient
private MultipartFile logoCustomerArea;
@Transient
private MultipartFile logoAssistant;
@Transient
private MultipartFile logoIdentityArea;
<omitting Getters and setters>
private Map<String, MultipartFile> getAllFiles() {
Map<String, MultipartFile> files = new HashMap<>();
files.put("logoPdf", logoPdf);
files.put("logoCustomerArea", logoCustomerArea);
files.put("logoAssistant", logoAssistant);
files.put("logoIdentityArea", logoIdentityArea);
return files;
}
public Map<String, MultipartFile> whichFiles() {
Map<String, MultipartFile> whichFiles = new HashMap<>();
for (String name : getAllFiles().keySet()) {
MultipartFile file = getAllFiles().get(name);
if (file != null && !file.isEmpty()) {
whichFiles.put(name, file);
}
}
return whichFiles;
}
}
如前所述,这不是全部代码,而是解决此特定问题的必要代码。
上传超大文件时抛出的异常是:
(java.io.IOException) java.io.IOException: UT000054: The maximum size 2097152 for an individual file in a multipart request was exceeded
或提到的FileUploadBase.FileSizeLimitExceedeException
最后但同样重要的是,表单页面的摘录
<div id="layoutOne" class="panel-collapse collapse">
<div class="panel-body">
<div class="form-group">
<label for="logoPdf" class="control-label" th:text="#{organizationcontext.groups.addmodal.logo.form.label}">LOGO-FORM</label>
<input type="file" th:field="*{style.logoPdf}" accept="image/*" />
</div>
<div class="form-group">
<label for="logoCustomerArea" class="control-label" th:text="#{organizationcontext.groups.addmodal.logo.customer.label}">LOGO-ORGANIZATION</label>
<input type="file" th:field="*{style.logoCustomerArea}" accept="image/*" />
</div>
<div class="form-group">
<label for="logoAssistant" class="control-label" th:text="#{organizationcontext.groups.addmodal.logo.assistant.label}">LOGO-ASSISTANT</label>
<input type="file" th:field="*{style.logoAssistant}" accept="image/*" />
</div>
<div class="form-group">
<label for="logoIdentityArea" class="control-label" th:text="#{organizationcontext.groups.addmodal.logo.id.label}">LOGO-ID</label>
<input type="file" th:field="*{style.logoIdentityArea}" accept="image/*" />
</div>
<div class="form-group" th:classappend="${#fields.hasErrors('style.cssUrl')}? has-error">
<label for="style.cssUrl" class="control-label" th:text="#{organizationcontext.groups.addmodal.css.external.label}">CSS-EXTERNAL</label>
<input th:field="*{style.cssUrl}" class="form-control" type="text" th:placeholder="#{placeholder.css.external}" />
</div>
<div class="form-group" th:classappend="${#fields.hasErrors('style.cssCode')}? has-error">
<label for="style.cssCode" class="control-label" th:text="#{organizationcontext.groups.addmodal.css.input.label}">CSS</label>
<textarea th:field="*{style.cssCode}" class="form-control" th:placeholder="#{placeholder.css.input}"></textarea>
</div>
</div>
</div>
如果您按照此处的问题进行操作,您应该已经意识到我们已经尝试了几种可能的解决方案,其中大部分来自此处。现在,过滤器捕获 RuntimeException
并检查 IOException
作为原因,此外,尺寸不再设置在 application.properties
中
如有任何帮助或建议,我们将不胜感激。
更多信息
因此,我调试了 StandardServletMultipartResolver
并发现它使用 ISO-8859-1-charset 进行解析。这确实产生了预期的效果,即使页面是 UTF-8 编码的并且请求对象也具有 UTF-8-Charset。我一直在尝试使用像这样的过滤器强制 ISO-Charset
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public Filter characterEncodingFilter() {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("ISO-8859-1");
characterEncodingFilter.setForceEncoding(true);
return characterEncodingFilter;
}
但是,由于某种原因,CommonsMultipartResolver
找到了一个 UTF-8 编码的请求对象,所以要么这个编码不起作用,要么我犯了另一个我没有看到的错误。
我也试图找到抛出异常的确切时刻,也许我自己扩展 class 并确保保留已经解析的表单数据,但到目前为止无济于事。
更多信息
正如此处另一个线程所建议的,我试图在请求中强制使用 ISO-8859-1 字符集。起初,这完全绕过了 CommonsMultipartResolver
并弄乱了我的文本,现在它过滤到正确的解析器,但是这个仍然声明多部分数据中没有文件。仅供参考,我使用的Filterclass:
private class MyMultiPartFilter extends MultipartFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
request.setCharacterEncoding("ISO-8859-1");
request.getParameterNames();
super.doFilterInternal(request, response, filterChain);
}
}
从中创建一个 Bean,并将 multipartResolver()-Bean 的名称更改为 filterMultipartResolver()
问题的解决方法是我在找的时候大致找到的。已发布 here。
由于WildFly和Undertow难以对付StandardServletMultipartResolver
,所以使用CommonsMultipartResolver
更为有效(甚至有必要)。但是,必须在处理其余 POST 数据之前调用它。
为了确保这一点,有必要调用一个 MultipartFilter
并创建一个 filterMultipartResolver
-Bean,如下所示:
@Bean
public CommonsMultipartResolver filterMultipartResolver() {
return new CommonsMultipartResolver();
}
@Bean
@Order(0)
public MultipartFilter multipartFilter() {
return new MultipartFilter();
}
这确保首先调用过滤器,然后调用解析器。唯一的缺点是没有开箱即用的方法来限制上传的单个文件大小。这可以通过设置 maxUploadSize(value)
来完成,这会限制总体请求大小。
最终编辑
所以,这就是我最终使用的,它可以有效地上传和处理超大文件。我不确定这在上传大文件时是否同样有效,因为这会在将请求转换为 FileItems
但在解析 FileItems
.
之前处理超大文件
我扩展了 CommonsMultipartResolver
来覆盖 parseRequest
,就像这样:
@Override
protected MultipartParsingResult parseRequest(HttpServletRequest request) {
String encoding = determineEncoding(request);
FileUpload fileUpload = prepareFileUpload(encoding);
List<FileItem> fileItems;
List<String> oversizedFields = new LinkedList<>();
try {
fileItems = ((ServletFileUpload) fileUpload).parseRequest(request);
} catch (FileUploadBase.SizeLimitExceededException ex) {
fileItems = Collections.emptyList();
request.setAttribute(ATTR_REQUEST_SIZE_EXCEEDED,
KEY_REQUEST_SIZE_EXCEEDED);
} catch (FileUploadException ex) {
throw new MultipartException(MULTIPART_UPLOAD_ERROR, ex);
}
if (maxFileSize > -1) {
for (FileItem fileItem : fileItems) {
if (fileItem.getSize() > maxFileSize) {
oversizedFields.add(fileItem.getFieldName());
fileItem.delete();
}
}
}
if (!oversizedFields.isEmpty()) {
request.setAttribute(ATTR_FIELDS_OVERSIZED, oversizedFields);
}
return parseFileItems((List<FileItem>) fileItems, encoding);
}
并添加了通过 bean 配置设置 maxFileSize 的方法。如果超过请求大小,所有值都将被删除,所以要小心,特别是如果你使用 _csrf-token
或类似的。
在控制器中,现在可以轻松检查添加的属性并在页面上放置错误消息。
我们在 Undertow 和 SpringBoot 上有一个项目 运行,正在尝试添加文件上传。第一次尝试成功,文件已通过使用 StandardServletMultipartResolver
绑定到适当的 Bean 并使用 application.properties
配置它。
然而,当涉及到错误处理时,我们 运行 陷入了可怕的困境。
我们通过将标准解析器配置为 100MB 并使用 CommonsMultipartResolver
找到了 "solution"。然后我们添加了一个像这样的过滤器
@Bean
public Filter filter() {
return new OncePerRequestFilter() {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
try {
filterChain.doFilter(request, response);
} catch (ServletException e) {
if (e.getCause()
.getClass()
.equals(org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException.class)) {
int requestSize = request.getContentLength();
Collection<Part> parts = request.getParts();
List<String> oversizedFields = new LinkedList<>();
long uploadSize = 0;
for (Part part : new ArrayList<>(parts)) {
if (uploadSize + part.getSize() > MAX_UPLOAD_SIZE) {
requestSize -= part.getSize();
oversizedFields.add(part.getName());
request.getParameterMap()
.remove(part.getName());
parts.remove(part);
} else {
uploadSize += part.getSize();
}
}
request.setAttribute("oversizedFields", oversizedFields);
SizeModifyingServletRequestWrapper requestWrapper = new SizeModifyingServletRequestWrapper(
request, requestSize, uploadSize);
filterChain.doFilter(requestWrapper, response);
}
}
}
};
}
请求包装器:
private static class SizeModifyingServletRequestWrapper extends
HttpServletRequestWrapper {
private int size;
private long sizeLong;
public SizeModifyingServletRequestWrapper(HttpServletRequest request,
int size, long sizeLong) {
super(request);
this.size = size;
this.sizeLong = sizeLong;
}
@Override
public int getContentLength() {
return size;
}
@Override
public long getContentLengthLong() {
return sizeLong;
}
@Override
public String getHeader(String name) {
if (FileUploadBase.CONTENT_LENGTH.equals(name)) {
return Integer.toString(size);
} else {
return super.getHeader(name);
}
}
}
@Controller
方法然后检查超大文件并将结果添加到 BindingResult
,这很好用,除了文件未绑定到 bean 的事实。
结果是 CommonsMultipartResolver
在尝试解析请求时在 ItemInputStream.makeAvailable()
中抛出一个 MalformedStreamException
,它总是 returns 消息 String ended unexpectedly
.
所以我们回到使用 StandardServletMultipartResolver
,并且能够捕获 RuntimeException
它抛出的很好,但是即使一个文件超过其大小边界,它也绝对不会提供任何表单数据。
我们完全被难住了,因为无论 Resolver 是否惰性工作都没有关系。如果有人对如何解决这个问题有任何进一步的想法,欢迎提出答案=)
更多参考代码:
摘自WebAppInitializer
@Bean(name = "multipartResolver")
public MultipartResolver multipartResolver() {
StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver();
multipartResolver.setResolveLazily(true);
return multipartResolver;
}
@Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
factory.setMaxFileSize("2MB");
factory.setMaxRequestSize("100MB");
return factory.createMultipartConfig();
}
从控制器中提取:
@RequestMapping(method = { RequestMethod.POST, RequestMethod.PUT })
public String saveOrganizationDetails(
@PathVariable(PATH_VARIABLE_ORGANIZATION_ID) String organizationId,
@ModelAttribute @Valid Organization organization,
BindingResult bindingResult, Model model,
RedirectAttributes redirectAttributes, WebRequest request) {
checkForOversizedFiles(request, bindingResult);
Map<String, MultipartFile> files = organization.getStyle().whichFiles();
}
private boolean checkForOversizedFiles(WebRequest request,
BindingResult bindingResult) {
if (request.getAttribute("oversizedFields", WebRequest.SCOPE_REQUEST) instanceof LinkedList) {
@SuppressWarnings("unchecked")
LinkedList<String> oversizedFiles = (LinkedList<String>) request
.getAttribute("oversizedFields", WebRequest.SCOPE_REQUEST);
for (String s : oversizedFiles) {
String errorCode = KEY_ORGANIZATION_LOGO_OVERSIZED_FILE + s;
bindingResult.rejectValue(s,
errorCode);
}
return true;
} else {
return false;
}
}
private void handleUpload(Map<String, MultipartFile> files,
OrganizationStyle style, BindingResult result) {
for (String filename : files.keySet()) {
if (processUpload(files.get(filename), filename)) {
style.setLogoFlag(filename);
} else {
result.reject(KEY_ORGANIZATION_LOGO_UPLOAD_FAILURE);
}
}
}
processUpload()
到目前为止还没有任何功能,这就是我不在此处包含它的原因。
从表单支持 Bean 中提取:
public class OrganizationStyle {
@Transient
private MultipartFile logoPdf;
@Transient
private MultipartFile logoCustomerArea;
@Transient
private MultipartFile logoAssistant;
@Transient
private MultipartFile logoIdentityArea;
<omitting Getters and setters>
private Map<String, MultipartFile> getAllFiles() {
Map<String, MultipartFile> files = new HashMap<>();
files.put("logoPdf", logoPdf);
files.put("logoCustomerArea", logoCustomerArea);
files.put("logoAssistant", logoAssistant);
files.put("logoIdentityArea", logoIdentityArea);
return files;
}
public Map<String, MultipartFile> whichFiles() {
Map<String, MultipartFile> whichFiles = new HashMap<>();
for (String name : getAllFiles().keySet()) {
MultipartFile file = getAllFiles().get(name);
if (file != null && !file.isEmpty()) {
whichFiles.put(name, file);
}
}
return whichFiles;
}
}
如前所述,这不是全部代码,而是解决此特定问题的必要代码。 上传超大文件时抛出的异常是:
(java.io.IOException) java.io.IOException: UT000054: The maximum size 2097152 for an individual file in a multipart request was exceeded
或提到的FileUploadBase.FileSizeLimitExceedeException
最后但同样重要的是,表单页面的摘录
<div id="layoutOne" class="panel-collapse collapse">
<div class="panel-body">
<div class="form-group">
<label for="logoPdf" class="control-label" th:text="#{organizationcontext.groups.addmodal.logo.form.label}">LOGO-FORM</label>
<input type="file" th:field="*{style.logoPdf}" accept="image/*" />
</div>
<div class="form-group">
<label for="logoCustomerArea" class="control-label" th:text="#{organizationcontext.groups.addmodal.logo.customer.label}">LOGO-ORGANIZATION</label>
<input type="file" th:field="*{style.logoCustomerArea}" accept="image/*" />
</div>
<div class="form-group">
<label for="logoAssistant" class="control-label" th:text="#{organizationcontext.groups.addmodal.logo.assistant.label}">LOGO-ASSISTANT</label>
<input type="file" th:field="*{style.logoAssistant}" accept="image/*" />
</div>
<div class="form-group">
<label for="logoIdentityArea" class="control-label" th:text="#{organizationcontext.groups.addmodal.logo.id.label}">LOGO-ID</label>
<input type="file" th:field="*{style.logoIdentityArea}" accept="image/*" />
</div>
<div class="form-group" th:classappend="${#fields.hasErrors('style.cssUrl')}? has-error">
<label for="style.cssUrl" class="control-label" th:text="#{organizationcontext.groups.addmodal.css.external.label}">CSS-EXTERNAL</label>
<input th:field="*{style.cssUrl}" class="form-control" type="text" th:placeholder="#{placeholder.css.external}" />
</div>
<div class="form-group" th:classappend="${#fields.hasErrors('style.cssCode')}? has-error">
<label for="style.cssCode" class="control-label" th:text="#{organizationcontext.groups.addmodal.css.input.label}">CSS</label>
<textarea th:field="*{style.cssCode}" class="form-control" th:placeholder="#{placeholder.css.input}"></textarea>
</div>
</div>
</div>
如果您按照此处的问题进行操作,您应该已经意识到我们已经尝试了几种可能的解决方案,其中大部分来自此处。现在,过滤器捕获 RuntimeException
并检查 IOException
作为原因,此外,尺寸不再设置在 application.properties
如有任何帮助或建议,我们将不胜感激。
更多信息
因此,我调试了 StandardServletMultipartResolver
并发现它使用 ISO-8859-1-charset 进行解析。这确实产生了预期的效果,即使页面是 UTF-8 编码的并且请求对象也具有 UTF-8-Charset。我一直在尝试使用像这样的过滤器强制 ISO-Charset
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public Filter characterEncodingFilter() {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("ISO-8859-1");
characterEncodingFilter.setForceEncoding(true);
return characterEncodingFilter;
}
但是,由于某种原因,CommonsMultipartResolver
找到了一个 UTF-8 编码的请求对象,所以要么这个编码不起作用,要么我犯了另一个我没有看到的错误。
我也试图找到抛出异常的确切时刻,也许我自己扩展 class 并确保保留已经解析的表单数据,但到目前为止无济于事。
更多信息
正如此处另一个线程所建议的,我试图在请求中强制使用 ISO-8859-1 字符集。起初,这完全绕过了 CommonsMultipartResolver
并弄乱了我的文本,现在它过滤到正确的解析器,但是这个仍然声明多部分数据中没有文件。仅供参考,我使用的Filterclass:
private class MyMultiPartFilter extends MultipartFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
request.setCharacterEncoding("ISO-8859-1");
request.getParameterNames();
super.doFilterInternal(request, response, filterChain);
}
}
从中创建一个 Bean,并将 multipartResolver()-Bean 的名称更改为 filterMultipartResolver()
问题的解决方法是我在找的时候大致找到的。已发布 here。
由于WildFly和Undertow难以对付StandardServletMultipartResolver
,所以使用CommonsMultipartResolver
更为有效(甚至有必要)。但是,必须在处理其余 POST 数据之前调用它。
为了确保这一点,有必要调用一个 MultipartFilter
并创建一个 filterMultipartResolver
-Bean,如下所示:
@Bean
public CommonsMultipartResolver filterMultipartResolver() {
return new CommonsMultipartResolver();
}
@Bean
@Order(0)
public MultipartFilter multipartFilter() {
return new MultipartFilter();
}
这确保首先调用过滤器,然后调用解析器。唯一的缺点是没有开箱即用的方法来限制上传的单个文件大小。这可以通过设置 maxUploadSize(value)
来完成,这会限制总体请求大小。
最终编辑
所以,这就是我最终使用的,它可以有效地上传和处理超大文件。我不确定这在上传大文件时是否同样有效,因为这会在将请求转换为 FileItems
但在解析 FileItems
.
我扩展了 CommonsMultipartResolver
来覆盖 parseRequest
,就像这样:
@Override
protected MultipartParsingResult parseRequest(HttpServletRequest request) {
String encoding = determineEncoding(request);
FileUpload fileUpload = prepareFileUpload(encoding);
List<FileItem> fileItems;
List<String> oversizedFields = new LinkedList<>();
try {
fileItems = ((ServletFileUpload) fileUpload).parseRequest(request);
} catch (FileUploadBase.SizeLimitExceededException ex) {
fileItems = Collections.emptyList();
request.setAttribute(ATTR_REQUEST_SIZE_EXCEEDED,
KEY_REQUEST_SIZE_EXCEEDED);
} catch (FileUploadException ex) {
throw new MultipartException(MULTIPART_UPLOAD_ERROR, ex);
}
if (maxFileSize > -1) {
for (FileItem fileItem : fileItems) {
if (fileItem.getSize() > maxFileSize) {
oversizedFields.add(fileItem.getFieldName());
fileItem.delete();
}
}
}
if (!oversizedFields.isEmpty()) {
request.setAttribute(ATTR_FIELDS_OVERSIZED, oversizedFields);
}
return parseFileItems((List<FileItem>) fileItems, encoding);
}
并添加了通过 bean 配置设置 maxFileSize 的方法。如果超过请求大小,所有值都将被删除,所以要小心,特别是如果你使用 _csrf-token
或类似的。
在控制器中,现在可以轻松检查添加的属性并在页面上放置错误消息。