Search code examples
javaspring-mvcexceptionspring-bootexceptionhandler

Questions about the size of the Springboot upload file


An error occurs when I upload the file size bigger than the set value. I want to catch this exception and return it to the browser.The e.getCause().getMessage() has a value , but not successfully return to browser. Normally, a piece of json will be displayed on the browser. handleFileFormatException is no problem, but handleIllegalStateException can't display any message and occurs "Unable to access this site" on the browser.The paths are all shown:localhost:8080. These two methods are almost the same, the difference is that FileFormatExceptio is my defined exception class, but IllegalStateException is not. Why didn't it return json entity to the browser. I don't know what to do.Who can help me? Thank you!

application.properties: application.properties

@ExceptionHandler @ExceptionHandler

ExceptionResponse

public class ExceptionResponse {

private String message;
private Integer code;


public ExceptionResponse(Integer code, String message){
    this.message = message;
    this.code = code;
}

public static ExceptionResponse create(Integer code, String message){
    return new ExceptionResponse(code, message);
}

public Integer getCode() {
    return code;
}
public String getMessage() {
    return message;
}

}

Console warning, NO error

 2017-07-31 17:10:50.388  WARN 10940 --- [nio-8080-exec-4] .m.m.a.ExceptionHandlerExceptionResolver : Resolved exception caused by Handler execution: org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (42990730) exceeds the configured maximum (10485760)

Browser press F12 enter image description here

enter image description here

Controller

@Controller
public class FileUploadController {

    private final StorageService storageService;

    @Autowired
    public FileUploadController(StorageService storageService) {
        this.storageService = storageService;
    }


   @GetMapping("/")
    public String listUploadedFiles(Model model) throws IOException {

        model.addAttribute("files", storageService
                .loadAll()
                .map(path ->
                        MvcUriComponentsBuilder
                                .fromMethodName(FileUploadController.class, "serveFile", path.getFileName().toString())
                                .build().toString())
                .collect(Collectors.toList()));

        return "index";
    }

    @GetMapping("/files/{filename:.+}")
    @ResponseBody
    public ResponseEntity<Resource> serveFile(@PathVariable String filename) {

        Resource file = storageService.loadAsResource(filename);
        return ResponseEntity
                .ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getFilename() + "\"")
                .body(file);
    }

    @PostMapping("/")
    public String handleFileUpload(@RequestParam("file") MultipartFile file,
                                   RedirectAttributes redirectAttributes){
        storageService.store(file);
        redirectAttributes.addFlashAttribute("message",
                "upload success! " + file.getOriginalFilename() + "!");
        return "redirect:/";
    }

getStatus

private HttpStatus getStatus(HttpServletRequest request) {
        Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
        if (statusCode == null) {
            return HttpStatus.INTERNAL_SERVER_ERROR;
        }
        return HttpStatus.valueOf(statusCode);
    }

Solution

  • You are missing the part where you set the http response status code when the exception is handled by your exception handler.

    • Add @ResponseStatus(value= HttpStatus.BAD_REQUEST) to your method.

    or

    • Add HttpServletResponse response to the method arguments list and call response.setStatus(HttpStatus.BAD_REQUEST.value()); before returning your object.