Beispiel für das Hochladen von MVC-Dateien
Spring verwendet die Schnittstelle vonMultipartResolver
, um die Datei-Uploads in der Webanwendung zu verarbeiten, zwei der Implementierungen:
-
StandardServletMultipartResolver
- Servlet 3.0-Analyse von mehrteiligen Anforderungen. -
CommonsMultipartResolver
- Classic commons-fileupload.jar
In diesem Artikel verwendete Tools:
-
Feder 4.3.5.FREIGABE
-
Maven 3
-
Tomcat 7 oder 8, Jetty 9 oder ein beliebiger Servlet 3.0-Container
Kurz gesagt, in diesem Artikel erfahren Sie, wie Sie mit dem Hochladen von Dateien in der Spring MVC-Webanwendung umgehen und wie Sie mit der beliebten Ausnahme "Maximale Dateigröße überschritten" umgehen.
Note
Dieser Artikel befasst sich mit der mehrteiligen Analyse von Servlet 3.0-Anforderungen.
P.S Article is updated from Spring 2.5.x to Spring 4.3.x
1. Projektstruktur
Eine Standard-Maven-Projektstruktur.
2. Projektabhängigkeit
Standard Spring-Abhängigkeiten, keine zusätzliche Bibliothek zum Hochladen von Dateien erforderlich.
pom.xml
4.0.0 com.example spring-mvc-file-upload war 1.0-SNAPSHOT Spring MVC file upload 1.8 4.3.5.RELEASE 1.2 3.1.0 1.1.3 1.7.12 org.springframework spring-webmvc ${spring.version} commons-logging commons-logging javax.servlet jstl ${jstl.version} javax.servlet javax.servlet-api ${servletapi.version} provided org.slf4j jcl-over-slf4j ${jcl.slf4j.version} ch.qos.logback logback-classic ${logback.version} org.apache.maven.plugins maven-compiler-plugin 3.3 ${jdk.version} org.eclipse.jetty jetty-maven-plugin 9.2.11.v20150529 10 /spring4upload org.apache.maven.plugins maven-eclipse-plugin 2.9 true true 2.0 /spring4upload
3. MultipartConfigElement
Erstellen Sie eine Servlet-Initialisierungsklasse und registrieren Sie einjavax.servlet.MultipartConfigElement
MyWebInitializer.java
package com.example; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; import javax.servlet.MultipartConfigElement; import javax.servlet.ServletRegistration; import java.io.File; public class MyWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { private int maxUploadSizeInMb = 5 * 1024 * 1024; // 5 MB @Override protected Class[] getServletConfigClasses() { return new Class[]{SpringWebMvcConfig.class}; } @Override protected String[] getServletMappings() { return new String[]{"/"}; } @Override protected Class[] getRootConfigClasses() { return null; } @Override protected void customizeRegistration(ServletRegistration.Dynamic registration) { // upload temp file will put here File uploadDirectory = new File(System.getProperty("java.io.tmpdir")); // register a MultipartConfigElement MultipartConfigElement multipartConfigElement = new MultipartConfigElement(uploadDirectory.getAbsolutePath(), maxUploadSizeInMb, maxUploadSizeInMb * 2, maxUploadSizeInMb / 2); registration.setMultipartConfig(multipartConfigElement); } }
Überprüfen Sie die Methodensignatur vonMultipartConfigElement.
public MultipartConfigElement(java.lang.String location, long maxFileSize, long maxRequestSize, int fileSizeThreshold)
4. Federkonfiguration
Registrieren Sie einemultipartResolver
-Bean und geben SieStandardServletMultipartResolver
zurück
SpringWebMvcConfig.java
package com.example; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.multipart.MultipartResolver; import org.springframework.web.multipart.support.StandardServletMultipartResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; @EnableWebMvc @Configuration @ComponentScan({"com.example"}) public class SpringWebMvcConfig extends WebMvcConfigurerAdapter { // Bean name must be "multipartResolver", by default Spring uses method name as bean name. @Bean public MultipartResolver multipartResolver() { return new StandardServletMultipartResolver(); } /* // if the method name is different, you must define the bean name manually like this : @Bean(name = "multipartResolver") public MultipartResolver createMultipartResolver() { return new StandardServletMultipartResolver(); }*/ @Bean public InternalResourceViewResolver viewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setViewClass(JstlView.class); viewResolver.setPrefix("/WEB-INF/views/jsp/"); viewResolver.setSuffix(".jsp"); return viewResolver; } }
In diesem Stadium ist das Multipart-Anforderungs-Parsing für Servlet 3.0 ordnungsgemäß konfiguriert, und Sie können mit dem Hochladen der Datei beginnen.
4. Einzelne Datei hochladen
4.1 Normal HTML form tag.
upload.jsp
Spring MVC file upload example
4.2 Another page to show the upload status.
uploadStatus.jsp
Upload Status
Message : ${message}
4.3 In the Controller, map the uploaded file to MultipartFile
UploadController.java
package com.example.controller; import org.springframework.stereotype.Controller; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.StringJoiner; @Controller public class UploadController { //Save the uploaded file to this folder private static String UPLOADED_FOLDER = "F://temp//"; @GetMapping("/") public String index() { return "upload"; } //@RequestMapping(value = "/upload", method = RequestMethod.POST) @PostMapping("/upload") // //new annotation since 4.3 public String singleFileUpload(@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes) { if (file.isEmpty()) { redirectAttributes.addFlashAttribute("message", "Please select a file to upload"); return "redirect:uploadStatus"; } try { // Get the file and save it somewhere byte[] bytes = file.getBytes(); Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename()); Files.write(path, bytes); redirectAttributes.addFlashAttribute("message", "You successfully uploaded '" + file.getOriginalFilename() + "'"); } catch (IOException e) { e.printStackTrace(); } return "redirect:/uploadStatus"; } @GetMapping("/uploadStatus") public String uploadStatus() { return "uploadStatus"; } }
5. Upload mehrerer Dateien
5.1 Just add more file input.
uploadMulti.jsp
Spring MVC multi files upload example
5.2 In Spring Controller, maps the multiple uploaded files to MultipartFile []
UploadController.java
//... @PostMapping("/uploadMulti") public String multiFileUpload(@RequestParam("files") MultipartFile[] files, RedirectAttributes redirectAttributes) { StringJoiner sj = new StringJoiner(" , "); for (MultipartFile file : files) { if (file.isEmpty()) { continue; //next pls } try { byte[] bytes = file.getBytes(); Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename()); Files.write(path, bytes); sj.add(file.getOriginalFilename()); } catch (IOException e) { e.printStackTrace(); } } String uploadedFileName = sj.toString(); if (StringUtils.isEmpty(uploadedFileName)) { redirectAttributes.addFlashAttribute("message", "Please select a file to upload"); } else { redirectAttributes.addFlashAttribute("message", "You successfully uploaded '" + uploadedFileName + "'"); } return "redirect:/uploadStatus"; } @GetMapping("/uploadMultiPage") public String uploadMultiPage() { return "uploadMulti"; } //...
6. Handle Maximale Upload-Größe überschritten
Deklariert a@ControllerAdvice
und fängt dieMultipartException
ab, um die beliebte Ausnahme für die maximale maximale Upload-Größe zu erreichen
GlobalExceptionHandler.java
package com.example.exception; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.multipart.MultipartException; import org.springframework.web.servlet.mvc.support.RedirectAttributes; @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(MultipartException.class) public String handleError1(MultipartException e, RedirectAttributes redirectAttributes) { redirectAttributes.addFlashAttribute("message", e.getCause().getMessage()); return "redirect:/uploadStatus"; } // For commons-fileupload solution /*@ExceptionHandler(MaxUploadSizeExceededException.class) public String handleError2(MaxUploadSizeExceededException e, RedirectAttributes redirectAttributes) { redirectAttributes.addFlashAttribute("message", e.getCause().getMessage()); return "redirect:/uploadStatus"; }*/ }
Tomcat Connection Reset
Wenn Sie eine Bereitstellung für Tomcat durchgeführt haben und die Dateigröße nicht abfangen konnten, kann dies durch die Einstellung von TomcatmaxSwallowSize
verursacht werden. Lesen Sie dies -Spring file upload and connection reset issue
7. DEMO
Holen Sie sich den folgenden Quellcode und testen Sie ihn mit dem eingebetteten Jetty-Servermvn jetty:run
.
7.1 Review the pom.xml
above, the embedded Jetty will deploy the web application on this /spring4upload
context.
Terminal
project $ mvn jetty:run //... [INFO] Started o.e.j.m.p.JettyWebAppContext@341672e{/spring4upload, file:/SpringMVCUploadExample/src/main/webapp/,AVAILABLE}{file:/SpringMVCUploadExample/src/main/webapp/} [WARNING] !RequestLog [INFO] Started ServerConnector@3ba1308d{HTTP/1.1}{0.0.0.0:8080} [INFO] Started @3743ms [INFO] Started Jetty Server [INFO] Starting scanner at interval of 10 seconds.
7.2 Access http://localhost:8080/spring4upload
7.3 Select a file ‘MyFirstExcel.xml‘ and upload it.
7.5 Select few files and upload it.
7.6 Select a file larger than 5mb, you will visit this page.
8. Quellcode herunterladen
Herunterladen -spring-mvc-file-upload-example.zip (10 KB)
P.S For Spring 2.5.x, try this Spring.2.5-file-upload-example.zip (10KB)