2015-03-31 10 views
5

Tôi có một tệp tải lên rất đơn giản được thiết lập với Khởi động mùa xuân. Tôi đã tự hỏi nếu có một cách dễ dàng để hiển thị một trang lỗi khi vượt quá kích thước tệp tối đa.Xử lý MultipartException với trang khởi động Spring và lỗi hiển thị

Tôi đã tải lên một ví dụ rất đơn giản về những gì tôi đang cố gắng đạt được on github.

Về cơ bản, ý tưởng là để bắt MultipartException trong một handler mùa xuân ngoại lệ toàn cầu:

@ControllerAdvice 
public class UploadExceptionHandler { 

    @ExceptionHandler(MultipartException.class) 
    public ModelAndView handleError(MultipartException exception) { 
    ModelAndView modelAndView = new ModelAndView(); 
    modelAndView.addObject("error", exception.getMessage()); 
    modelAndView.setViewName("uploadPage"); 
    return modelAndView; 
    } 
} 

Bộ điều khiển mà xử lý các tập tin tải lên là thực sự đơn giản:

@RequestMapping("/") 
public String uploadPage() { 
    return "uploadPage"; 
} 

@RequestMapping(value = "/", method = RequestMethod.POST) 
public String onUpload(@RequestParam MultipartFile file) { 
    System.out.println(file.getOriginalFilename()); 
    return "uploadPage"; 
} 

Và uploadPage.html mẫu thymeleaf liên kết với nó quá:

<!DOCTYPE html> 
<html xmlns:th="http://www.thymeleaf.org"> 
<head lang="en"> 
    <title>Upload</title> 
</head> 
<body> 

<div style="color: red" th:text="${error}" th:if="${error}"> 
    Error during upload 
</div> 

<form th:action="@{/}" method="post" enctype="multipart/form-data"> 
    <input type="file" id="file" name="file"/> 
    <button type="submit" name="save">Submit</button> 
</form> 
</body> 
</html> 

Ý tưởng là t o hiển thị thông báo lỗi trong cùng một trang tải lên khi tệp quá lớn.

Đó là sự hiểu biết của tôi rằng người ta sẽ cấu hình MultipartResolver Spring để giải quyết trường hợp ngoại lệ uể oải và có thể bắt những trường hợp ngoại lệ ở cấp Spring (MVC xử lý ngoại lệ) nhưng mã này dường như không giúp:

@Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) 
public StandardServletMultipartResolver multipartResolver() { 
    StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver(); 
    multipartResolver.setResolveLazily(true); 
    return multipartResolver; 
} 

Vì vậy, trước khi tôi sử dụng các biện pháp cực đoan như bộ lọc hoặc mở rộng MultipartResolver ...

Bạn có biết cách xử lý các ngoại lệ đó với Spring MVC không?

Trả lời

Nhờ @ rossen-stoyanchev. Đây là những gì tôi đã kết thúc làm:

@RequestMapping("uploadError") 
public ModelAndView onUploadError(HttpServletRequest request) { 
    ModelAndView modelAndView = new ModelAndView("uploadPage"); 
    modelAndView.addObject("error", request.getAttribute(WebUtils.ERROR_MESSAGE_ATTRIBUTE)); 
    return modelAndView; 
} 

@Bean 
public EmbeddedServletContainerCustomizer containerCustomizer() { 
    return container -> container.addErrorPages(new ErrorPage(MultipartException.class, "/uploadError")); 
} 

Làm việc như một sự quyến rũ và cảm thấy như một giải pháp thanh lịch. Tôi đã cập nhật dự án trên github nếu ai đó quan tâm. Rất cám ơn!

+0

Một phần của sự cố có thể liên quan đến thực tế là các yêu cầu nhiều phần không thực sự được liên kết với vòng đời của Spring MVC. Tôi có nghĩa là xử lý ngoại lệ có thể được gọi nhiều lần trên cùng một trang nếu tập tin là đủ lớn. Có gì khó hiểu là nó có thể làm việc, đôi khi, khi thực sự không giải quyết ngoại lệ một cách lười biếng nhưng hành vi này dường như không nhất quán. –

+0

Giải pháp không hiệu quả đối với tôi. Tôi có trang lỗi cho MultipartException được thêm vào và tôi vẫn gặp sự cố khi cố gắng tải lên một tệp lớn. Bạn có thể giúp tôi được không? – Greyshack

+0

Kho lưu trữ vẫn đang hoạt động: https://github.com/geowarin/multipartException nó sẽ hoạt động :) –

Trả lời

2

Phân tích yêu cầu nhiều phần diễn ra trước khi trình xử lý được chọn và do đó không có @Controller và do đó không có @ControllerAdvice để nói đến. Bạn có thể sử dụng một ErrorController (xem http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-web-applications.html#boot-features-error-handling) cho điều đó.

BTW bạn không cần @RequestParam. Đủ là kiểu đối số là MultipartFile.

+0

Nhưng phải làm gì nếu tôi chỉ muốn trả lại đối tượng cho trang ajax- – gstackoverflow

Các vấn đề liên quan