2015-03-31 10 views
5

Ho un semplice upload di file impostato con Spring Boot. Mi chiedevo se c'era un modo semplice per visualizzare una pagina di errore quando viene superata la dimensione massima del file.Gestione di MultipartException con Spring Boot e pagina di errore di visualizzazione

Ho caricato un esempio molto semplice di ciò che sto cercando di ottenere on github.

In sostanza, l'idea è di prendere il MultipartException in un gestore di eccezioni Spring Global:

@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; 
    } 
} 

Il controllore che gestisce il caricamento di file è molto semplice:

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

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

E l'uploadPage.html modello di thymeleaf ad esso associato:

<!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> 

L'idea è t o visualizza un messaggio di errore nella stessa pagina di caricamento quando il file è troppo grande.

E 'stata la mia comprensione che si potrebbe configurare MultipartResolver di primavera per risolvere eccezioni pigramente ed essere in grado di catturare le eccezioni a livello di primavera (MVC gestori di eccezioni) ma questo codice non sembra aiutare:

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

Così prima di ricorrere a misure estreme come un filtro o estendere il MultipartResolver ...

Conoscete un modo pulito per gestire tali eccezioni con Spring MVC?

risposta

Grazie a @ Rossen-stoyanchev. Ecco quello che ho finito per fare:

@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")); 
} 

funziona come un fascino e si sente come una soluzione elegante. Ho aggiornato il progetto su github se qualcuno è interessato. Mille grazie!

+0

Parte del problema potrebbe dipendere dal fatto che le richieste multipart non sono realmente collegate al ciclo di vita di Spring MVC. Voglio dire che il gestore delle eccezioni può essere chiamato più volte sulla stessa pagina se il file è abbastanza grande. Ciò che è sconcertante è che può funzionare, a volte, quando in realtà non risolve le eccezioni pigramente, ma questo comportamento non sembra essere coerente. –

+0

La soluzione non funziona per me. Ho aggiunto la pagina di errore per MultipartException e continuo a causare un arresto anomalo quando provo a caricare un file di grandi dimensioni. Mi potete aiutare? – Greyshack

+0

Il repository è ancora attivo: https://github.com/geowarin/multipartException dovrebbe funzionare :) –

risposta

2

L'analisi di richiesta multipart avviene prima che un gestore sia selezionato e quindi non esiste nessun @Controller e quindi nessun @ControllerAdvice di cui parlare ancora. Puoi usare un ErrorController (vedi http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-web-applications.html#boot-features-error-handling) per quello.

BTW non è necessario @RequestParam. È sufficiente che il tipo di argomento sia MultipartFile.

+0

Ma cosa fare se voglio restituire solo oggetto a ajax- non pagina – gstackoverflow

Problemi correlati