1. Обзор
В предыдущих руководствах мы представили основы обработки форм и изучили библиотеку тегов форм в Spring MVC.
В этом руководстве мы сосредоточимся на том, что предлагает Spring для многокомпонентной поддержки (загрузки файлов) в веб-приложениях.
Spring позволяет нам включить эту поддержку составных частей с помощью подключаемых объектов MultipartResolver .
Платформа предоставляет одну реализацию MultipartResolver
для использования с Commons FileUpload и другую для использования с анализом составных запросов Servlet 3.0 .
После настройки MultipartResolver
мы увидим, как загрузить один файл и несколько файлов.
Мы также коснемся Spring Boot.
2. Загрузить файл Commons
Чтобы использовать CommonsMultipartResolver
для обработки загрузки файла, нам нужно добавить следующую зависимость:
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
Теперь мы можем определить bean- компонент CommonsMultipartResolver
в нашей конфигурации Spring.
Этот MultipartResolver
поставляется с рядом методов set
для определения таких свойств, как максимальный размер для загрузки:
@Bean(name = "multipartResolver")
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
multipartResolver.setMaxUploadSize(100000);
return multipartResolver;
}
Здесь нам нужно управлять различными свойствами CommonsMultipartResolver
в самом определении Бина.
3. С сервлетом 3.0
Чтобы использовать многокомпонентный синтаксический анализ Servlet 3.0
, нам нужно настроить пару частей приложения.
Во-первых, нам нужно установить MultipartConfigElement
в нашей регистрации
DispatcherServlet
`` :
public class MainWebAppInitializer implements WebApplicationInitializer {
private String TMP_FOLDER = "/tmp";
private int MAX_UPLOAD_SIZE = 5 * 1024 * 1024;
@Override
public void onStartup(ServletContext sc) throws ServletException {
ServletRegistration.Dynamic appServlet = sc.addServlet("mvc", new DispatcherServlet(
new GenericWebApplicationContext()));
appServlet.setLoadOnStartup(1);
MultipartConfigElement multipartConfigElement = new MultipartConfigElement(TMP_FOLDER,
MAX_UPLOAD_SIZE, MAX_UPLOAD_SIZE * 2, MAX_UPLOAD_SIZE / 2);
appServlet.setMultipartConfig(multipartConfigElement);
}
}
В объекте MultipartConfigElement
мы настроили место хранения, максимальный размер отдельного файла, максимальный размер запроса (в случае нескольких файлов в одном запросе) и размер, при котором ход загрузки файла сбрасывается в место хранения.
Эти настройки должны применяться на уровне регистрации сервлета, потому что Servlet 3.0
не позволяет их регистрировать в MultipartResolver
, как в случае с CommonsMultipartResolver
.
Как только это будет сделано, мы можем добавить StandardServletMultipartResolver
в нашу конфигурацию Spring :
@Bean
public StandardServletMultipartResolver multipartResolver() {
return new StandardServletMultipartResolver();
}
4. Загрузка файла ** **
Чтобы загрузить наш файл, мы можем создать простую форму, в которой мы используем тег ввода HTML с
type='file'
.
Независимо от выбранной нами конфигурации обработки загрузки, нам необходимо установить для атрибута кодирования формы значение multipart/form-data
.
Это позволяет браузеру узнать, как кодировать форму:
<form:form method="POST" action="/spring-mvc-xml/uploadFile" enctype="multipart/form-data">
<table>
<tr>
<td><form:label path="file">Select a file to upload</form:label></td>
<td><input type="file" name="file" /></td>
</tr>
<tr>
<td><input type="submit" value="Submit" /></td>
</tr>
</table>
</form>
Чтобы сохранить загруженный файл, мы можем использовать переменную MultipartFile .
Мы можем получить эту переменную из параметра запроса внутри метода нашего контроллера:
@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
public String submit(@RequestParam("file") MultipartFile file, ModelMap modelMap) {
modelMap.addAttribute("file", file);
return "fileUploadView";
}
Класс MultipartFile
предоставляет доступ к сведениям о загруженном файле , включая имя файла, тип файла и т. д.
Мы можем использовать простую HTML-страницу для отображения этой информации:
<h2>Submitted File</h2>
<table>
<tr>
<td>OriginalFileName:</td>
<td>${file.originalFilename}</td>
</tr>
<tr>
<td>Type:</td>
<td>${file.contentType}</td>
</tr>
</table>
5. Загрузка нескольких файлов
Чтобы загрузить несколько файлов в одном запросе, мы просто помещаем в форму несколько полей ввода файла:
<form:form method="POST" action="/spring-mvc-java/uploadMultiFile" enctype="multipart/form-data">
<table>
<tr>
<td>Select a file to upload</td>
<td><input type="file" name="files" /></td>
</tr>
<tr>
<td>Select a file to upload</td>
<td><input type="file" name="files" /></td>
</tr>
<tr>
<td>Select a file to upload</td>
<td><input type="file" name="files" /></td>
</tr>
<tr>
<td><input type="submit" value="Submit" /></td>
</tr>
</table>
</form:form>
Нам нужно позаботиться о том, чтобы каждое поле ввода имело одно и то же имя, чтобы к нему можно было получить доступ как к массиву MultipartFile
:
@RequestMapping(value = "/uploadMultiFile", method = RequestMethod.POST)
public String submit(@RequestParam("files") MultipartFile[] files, ModelMap modelMap) {
modelMap.addAttribute("files", files);
return "fileUploadView";
}
Теперь мы можем просто перебрать этот массив, чтобы отобразить информацию о файлах:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Spring MVC File Upload</title>
</head>
<body>
<h2>Submitted Files</h2>
<table>
<c:forEach items="${files}" var="file">
<tr>
<td>OriginalFileName:</td>
<td>${file.originalFilename}</td>
</tr>
<tr>
<td>Type:</td>
<td>${file.contentType}</td>
</tr>
</c:forEach>
</table>
</body>
</html>
6. Загрузка файлов с дополнительными данными формы
Мы также можем отправить дополнительную информацию на сервер вместе с загружаемым файлом.
Нам просто нужно включить необходимые поля в форму:
<form:form method="POST"
action="/spring-mvc-java/uploadFileWithAddtionalData"
enctype="multipart/form-data">
<table>
<tr>
<td>Name</td>
<td><input type="text" name="name" /></td>
</tr>
<tr>
<td>Email</td>
<td><input type="text" name="email" /></td>
</tr>
<tr>
<td>Select a file to upload</td>
<td><input type="file" name="file" /></td>
</tr>
<tr>
<td><input type="submit" value="Submit" /></td>
</tr>
</table>
</form:form>
В контроллере мы можем получить все данные формы с помощью аннотации @RequestParam
:
@PostMapping("/uploadFileWithAddtionalData")
public String submit(
@RequestParam MultipartFile file, @RequestParam String name,
@RequestParam String email, ModelMap modelMap) {
modelMap.addAttribute("name", name);
modelMap.addAttribute("email", email);
modelMap.addAttribute("file", file);
return "fileUploadView";
}
Как и в предыдущих разделах, мы можем использовать HTML-страницу с тегами JSTL
для отображения информации.
Мы также можем инкапсулировать все поля формы в класс модели и использовать аннотацию @ModelAttribute
в контроллере. Это было бы полезно, когда вместе с файлом есть много дополнительных полей.
Давайте посмотрим на код:
public class FormDataWithFile {
private String name;
private String email;
private MultipartFile file;
// standard getters and setters
}
@PostMapping("/uploadFileModelAttribute")
public String submit(@ModelAttribute FormDataWithFile formDataWithFile, ModelMap modelMap) {
modelMap.addAttribute("formDataWithFile", formDataWithFile);
return "fileUploadView";
}
7. Загрузка загрузочного файла Spring
Если мы используем Spring Boot, все, что мы видели до сих пор, остается в силе.
Тем не менее, Spring Boot упрощает настройку и запускает все без особых хлопот.
В частности, нет необходимости настраивать какой-либо сервлет , так как Boot зарегистрирует и настроит его за нас, при условии, что мы включим веб-модуль в наши зависимости:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.6.1</version>
</dependency>
Мы можем найти последнюю версию spring-boot-starter-web
на Maven Central.
Если мы хотим контролировать максимальный размер загружаемого файла, мы можем отредактировать наш application.properties
:
spring.servlet.multipart.max-file-size=128KB
spring.servlet.multipart.max-request-size=128KB
Мы также можем контролировать, включена ли загрузка файлов и место для загрузки файлов:
spring.servlet.multipart.enabled=true
spring.servlet.multipart.location=${java.io.tmpdir}
Обратите внимание, что мы использовали ${java.io.tmpdir}
для определения местоположения загрузки, чтобы мы могли использовать временное местоположение для разных операционных систем.
8. Заключение
В этой статье мы рассмотрели различные способы настройки поддержки составных частей в Spring. Используя их, мы можем поддерживать загрузку файлов в наших веб-приложениях.
Реализацию этого туториала можно найти в проекте GitHub . Когда проект выполняется локально, пример формы доступен по адресу http://localhost:8080/spring-mvc-java/fileUpload.