file-upload - spring boot文件上传在发生MultipartException时执行两次

标签 file-upload spring-boot

我想使用spring-boot上传文件,并且我已经配置了正确的属性,并且我也确保 Controller 是正确的,但奇怪的是,当我尝试上传超过限制的文件时, Controller 执行了两次,我期望的是一个错误的json消息,而我得到的是Postman下没有响应。

这是我的 Controller ,

@RestController
public class FileUploadController implements HandlerExceptionResolver {
    private static final Logger LOGGER = LoggerFactory.getLogger(FileUploadController.class);

    private static final String UPLOAD_PATH = "upload";

    @ResponseBody
    @RequestMapping(value = "/upload", method = RequestMethod.POST, consumes = "multipart/form-data", produces = "application/json;charset=UTF-8")
    public String upload(final MultipartFile file) {
        try {
            final Result<String> result = new Result<>();
            if (file.isEmpty()) {
                result.setSuccess(false);
                result.setMessage("file is empty");
                return Constants.OBJECT_MAPPER.writeValueAsString(result);
            }

            final File outputFile = new File(UPLOAD_PATH, UUID.randomUUID().toString());
            FileUtils.writeByteArrayToFile(outputFile, file.getBytes());

            result.setSuccess(true);
            result.setMessage(outputFile.toString());
            return Constants.OBJECT_MAPPER.writeValueAsString(result);
        } catch (final Exception ex) {
            LOGGER.error(ex.getMessage(), ex);
            return ExceptionResultBuilder.build(ex);
        }
    }

    @Override
    public ModelAndView resolveException(final HttpServletRequest request, final HttpServletResponse response, final Object handler, final Exception ex) {
        final ModelAndView modelAndView = new ModelAndView();
        modelAndView.setView(new MappingJackson2JsonView());
        final Map<String, Object> map = new HashMap<>();
        map.put("success", false);
        if (ex instanceof MultipartException) {
            // if (LOGGER.isDebugEnabled()) {
            LOGGER.info(ex.getMessage(), ex);
            // }
            final Throwable rootCause = ((MultipartException) ex).getRootCause();
            if (rootCause instanceof SizeLimitExceededException) {
                map.put("message", "request too large");
            } else if (rootCause instanceof FileSizeLimitExceededException) {
                map.put("message", "file too large");
            } else {
                map.put("message", "其他异常: " + rootCause.getMessage());
            }
        } else {
            LOGGER.error(ex.getMessage(), ex);
        }
        modelAndView.addAllObjects(map);
        return modelAndView;
    }
}

这是我用于文件上传的属性片段,

# MULTIPART (MultipartProperties)
multipart.enabled=true
multipart.max-file-size=5Mb
multipart.max-request-size=10Mb

如果我尝试上传一个大于5M的文件,我会在Postman下得到如下结果(文件大小为5208k) enter image description here 如果我尝试上传 5M 到 10M 之间的文件,我会收到此错误,(文件大小为 9748k) enter image description here

我调试到 Controller 中,发现resolveException方法在一次上传中执行了两次。

有人给我一些建议吗?

最佳答案

最新的代码列表在这里,我仍然得到相同的结果,

@RestController
@ControllerAdvice
public class FileUploadController {
    private static final Logger LOGGER = LoggerFactory.getLogger(FileUploadController.class);

    private static final String UPLOAD_PATH = "upload";

    @RequestMapping(value = "/upload", method = RequestMethod.POST, consumes = "multipart/form-data", produces = "application/json;charset=UTF-8")
    public HttpEntity<?> upload(final MultipartFile file) {
        try {
            final Result<String> result = new Result<>();
            if (file == null || file.isEmpty()) {
                result.setSuccess(false);
                result.setMessage("上传的文件为空");
                return new ResponseEntity<Result<?>>(result, HttpStatus.OK);
            }

            final File outputFile = new File(UPLOAD_PATH, UUID.randomUUID().toString());
            FileUtils.writeByteArrayToFile(outputFile, file.getBytes());

            result.setSuccess(true);
            result.setMessage(outputFile.toString());
            return new ResponseEntity<Result<?>>(result, HttpStatus.OK);
        } catch (final Exception ex) {
            LOGGER.error(ex.getMessage(), ex);
            return ExceptionResultBuilder.build(ex);
        }
    }

    @ExceptionHandler(MultipartException.class)
    public HttpEntity<?> multipartExceptionHandler(final MultipartException exception) {
        LOGGER.error(exception.getMessage(), exception);
        try {
            final Result<String> result = new Result<>();
            result.setSuccess(false);

            final Throwable rootCause = ((MultipartException) exception).getRootCause();
            if (rootCause instanceof SizeLimitExceededException) {
                result.setMessage("请求过大");
            } else if (rootCause instanceof FileSizeLimitExceededException) {
                result.setMessage("文件过大");
            } else {
                result.setMessage("未知错误");
            }
            return new ResponseEntity<Result<?>>(result, HttpStatus.OK);
        } catch (final Exception ex) {
            LOGGER.error(ex.getMessage(), ex);
            return ExceptionResultBuilder.build(ex);
        }
    }
}

关于file-upload - spring boot文件上传在发生MultipartException时执行两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34587268/

相关文章:

spring-boot - 使用 spring 集成 aws 轮询文件的 S3 存储桶和处理

java - 一个 Spring 应用程序中的多个 WebSecurityConfig

asp.net - 跟踪网络服务器上旧的上传文件 - 您如何知道哪些文件不再使用?

ruby - 使用 Paperclip gem,如何根据方向修改应用于上传的样式尺寸?

java - 创建 CSV 文件而不将其保存到文件系统中

java - 使用 log4j2 进行 Spring 启动。配置 log4j2 Spring-lookup

java - Spring-boot用jackson改变json响应结构

java - 使用 Servlet 上传文件?

java - 未捕获的语法错误 : Unexpected token <

javascript - 无法使用 AJAX 上传大于 50kb 的文件