Tomcat 7 или 8, Jetty 9 или любой контейнер Servlet 3.0
Вкратце, в этой статье показано, как обрабатывать загрузку файлов в веб-приложении Spring MVC, а также как обрабатывать популярное исключение максимального превышенного размера файла.
Note В этой статье основное внимание уделяется синтаксическому анализу многостраничного запроса сервлета 3.0.
P.S Article is updated from Spring 2.5.x to Spring 4.3.x
1. Структура проекта
Стандартная структура проекта Maven.
2. Зависимость проекта
Стандартные зависимости Spring, нет необходимости в дополнительной библиотеке для загрузки файлов.
public MultipartConfigElement(java.lang.String location,
long maxFileSize,
long maxRequestSize,
int fileSizeThreshold)
4. Конфигурация пружины
Зарегистрируйте bean-компонентmultipartResolver и вернетStandardServletMultipartResolver
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;
}
}
На этом этапе синтаксический анализ многочастного запроса Servlet 3.0 настроен правильно, и вы можете начать загрузку файла.
4. Загрузка одного файла
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. Загрузка нескольких файлов
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 []
6. Обработка Максимальный размер загрузки превышен
Для обработки популярного исключения превышения максимального размера загрузки объявляет@ControllerAdvice и перехватываетMultipartException
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 Если вы развернули систему на Tomcat и не смогли обнаружить исключение превышения размера файла, это может быть вызвано настройкой TomcatmaxSwallowSize. Прочтите это -Spring file upload and connection reset issue
7. DEMO
Получите приведенный ниже исходный код и протестируйте с помощью встроенного сервера Jettymvn jetty:run.
7.1 Review the pom.xml above, the embedded Jetty will deploy the web application on this /spring4upload context.
Терминал
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.