我有简单的SpringBoot应用程序文件上传功能,其中最大文件上传文件大小为2 MB。
我已配置multipart.max-file-size=2MB
它工作正常。
但是当我尝试上传大小超过2 MB的文件时,我想处理该错误并显示错误消息。
为此,我让我的控制器实现HandlerExceptionResolver
并实现resolveException()
,如下所示:
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception exception)
{
Map<String, Object> model = new HashMap<String, Object>();
if (exception instanceof MaxUploadSizeExceededException)
{
model.put("msg", exception.getMessage());
} else
{
model.put("msg", "Unexpected error: " + exception.getMessage());
}
return new ModelAndView("homepage", model);
}
问题是我获得的异常是 MultipartException 而不是 MaxUploadSizeExceededException 。
堆栈跟踪是: 无法解析多部分servlet请求;嵌套异常是java.lang.IllegalStateException:org.apache.tomcat.util.http.fileupload.FileUploadBase $ FileSizeLimitExceededException:字段myFile超过其允许的最大大小2097152字节。
如果文件大小超出原因,为什么我 MaxUploadSizeExceededException ?我得到它的父Exception MultipartException ,除了文件大小超出之外,还可能出于许多其他原因。
对此有何想法?
答案 0 :(得分:3)
我遇到了同样的问题,看起来只有Commons File Upload实现的MultipartResolver抛出MaxUploadSizeExceededException而不是MultipartResolver Servlet 3.0实现。
这是我到目前为止所做的。这里的关键是允许在控制器上检查文件,然后您可以验证大小并设置错误。
在下面设置多部分属性 多: max-file-size:-1 max-request-size:-1
设置Tomcat 8(maxSwallowSize =“ - 1”)
在控制器上,添加逻辑以检查大小
if(fileAttachment.getSize()&gt; 10485760){ 抛出新的MaxUploadSizeExceededException(fileAttachment.getSize()); }
答案 1 :(得分:0)
application.properties中的以下值对我有用。它似乎使文件大小可以接受
multipart.maxFileSize=-1
multipart.maxRequestSize=-1
现在您需要在控制器端添加逻辑。
@PostMapping("/upload")
public String handleFileUpload(@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes) {
long size = file.getSize();
if(size > 10000000)
{
redirectAttributes.addFlashAttribute("message",
"You file " + file.getOriginalFilename() + "! has not been successfully uploaded. Requires less than 10 MB size.");
return "redirect:/upload";
}
}
答案 2 :(得分:0)
这不是很好,但我的快速和肮脏的解决方案是检查MultipartException
消息字符串是否包含文本SizeLimitExceededException
并从该消息中提取最大文件大小信息。
在我的情况下,在tomcat 8.0.x上抛出的异常是 org.apache.tomcat.util.http.fileupload.FileUploadBase $ SizeLimitExceededException:请求被拒绝,因为它的大小(177351)超过了配置的最大值(2048)
请记住,正如aalmero指出的那样,如果你使用的是CommonsMultipartResolver
而不是StandardServletMultipartResolver
,那么会抛出MaxUploadSizeExceededException
,这样可以更好地处理。以下代码处理由多部分解析器策略抛出的MultipartException
:
@ControllerAdvice
public class MultipartExceptionExceptionHandler {
@ExceptionHandler(MultipartException.class)
public String handleMultipartException(MultipartException ex, RedirectAttributes ra) {
String maxFileSize = getMaxUploadFileSize(ex);
if (maxFileSize != null) {
ra.addFlashAttribute("errors", "Uploaded file is too large. File size cannot exceed " + maxFileSize + ".");
}
else {
ra.addFlashAttribute("errors", ex.getMessage());
}
return "redirect:/";
}
private String getMaxUploadFileSize(MultipartException ex) {
if (ex instanceof MaxUploadSizeExceededException) {
return asReadableFileSize(((MaxUploadSizeExceededException)ex).getMaxUploadSize());
}
String msg = ex.getMessage();
if (msg.contains("SizeLimitExceededException")) {
String maxFileSize = msg.substring(msg.indexOf("maximum")).replaceAll("\\D+", "");
if (StringUtils.isNumeric(maxFileSize)) {
return asReadableFileSize(Long.valueOf(maxFileSize));
}
}
return null;
}
// http://stackoverflow.com/a/5599842/225217
private static String asReadableFileSize(long size) {
if(size <= 0) return "0";
final String[] units = new String[] { "B", "kB", "MB", "GB", "TB" };
int digitGroups = (int) (Math.log10(size)/Math.log10(1024));
return new DecimalFormat("#,##0.#").format(size/Math.pow(1024, digitGroups)) + " " + units[digitGroups];
}
}