Вопрос или проблема
У меня есть приложение на Spring-MVC. В контроллере я сопоставлял данные форм с POJO с помощью @ModelAttribute. Теперь мне нужно, чтобы форма также отправляла файл. Я внес необходимые изменения в JSP файл и файлы POJO. Но теперь значения не сопоставляются.
Единственная проблема заключается в том, что определить резолвер для многочастных данных по умолчанию не представляется возможным. Это связано с тем, что код, который ранее находился в Struts и теперь был перенесен в Spring, разбирает запрос в самом бизнес-логике.
Что мне делать?
Контроллер:
@RequestMapping(value = "/getUserDetails", method = RequestMethod.POST, consumes = "multipart/form-data")
public String getUserDetails(@ModelAttribute("user") User user) {
System.out.println(user);
return "display-user";
}
JSP файл:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Демо форма</title>
</head>
<body>
<form action="getUserDetails" method="POST" enctype="multipart/form-data">
<table>
<tr>
<td>Имя: </td>
<td><input type="text" name="name"></td>
</tr>
<tr>
<td>Фамилия: </td>
<td><input type="text" name="lastName"></td>
</tr>
<tr>
<td>Возраст: </td>
<td><input type="number" name="age" step="1"></td>
</tr>
<tr>
<td>Оценки: </td>
<td><input type="number" name="marks"></td>
</tr>
<tr>
<td>Дата рождения: </td>
<td><input type="date" name="dob"></td>
</tr>
<tr>
<td>Файл: </td>
<td><input type="file" name="file"></td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit">
<input type="reset">
</td>
</tr>
</table>
</form>
</body>
</html>
POJO пользователя:
package com.habib.model;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.multipart.MultipartFile;
import java.util.Date;
public class User {
private String name;
private String lastName;
private int age;
private double marks;
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
private Date dob;
MultipartFile file;
public MultipartFile getFile() {
return file;
}
public void setFile(MultipartFile file) {
this.file = file;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Date getDob() {
return dob;
}
public void setDob(Date dob) {
this.dob = dob;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getMarks() {
return marks;
}
public void setMarks(double marks) {
this.marks = marks;
}
@Override
public String toString() {
return "User{" +
"name="" + name + "\'' +
", lastName="" + lastName + "\'' +
", age=" + age +
", marks=" + marks +
", date=" + dob.toLocaleString() +
'}';
}
}
Ответ или решение
Для разрешения проблемы с обработкой многокомпонентного запроса в Spring Framework, вам нужно учесть несколько важных аспектов, учитывая, что использование конфигурации мультипартного разрешателя по умолчанию не является подходящим вариантом в вашем случае.
Шаг 1: Конфигурация контроллера
В вашем контроллере, метод, который обрабатывает multipart, должен принимать объект MultipartFile
рядом с вашим объектом User
. Это связано с тем, что при работе с файлами в Spring MVC мы обычно используем аннотацию @RequestParam
для числовых параметров. Поэтому ваш код можно изменить следующим образом:
@RequestMapping(value = "/getUserDetails", method = RequestMethod.POST, consumes = "multipart/form-data")
public String getUserDetails(@ModelAttribute("user") User user,
@RequestParam("file") MultipartFile file) {
user.setFile(file); // Устанавливаем файл в объект User
System.out.println(user);
return "display-user";
}
Шаг 2: Обновление JSP файла
Ваш JSP файл уже корректно настроен для отправки файлов. Убедитесь, что используете enctype="multipart/form-data"
в теге формы, что вы и сделали. Также проверьте правильность указания имени файла в input
:
<input type="file" name="file">
Убедитесь, что все поля формы имеют правильные имена, которые соответствуют полям вашего POJO User
.
Шаг 3: Настройка MultipartResolver
Так как указано, что нельзя использовать конфигурацию по умолчанию, вам нужно создать и зарегистрировать свой собственный MultipartResolver
. Например, вы можете использовать StandardServletMultipartResolver
, что позволяет обрабатывать multipart-запросы.
Добавьте следующий код в ваш класc конфигурации Spring:
import org.springframework.context.annotation.Bean;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
@Bean
public MultipartResolver multipartResolver() {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setMaxUploadSize(1024000); // Максимальный размер файла в байтах (пример: 1MB)
return resolver;
}
Шаг 4: Проверка модуля зависимости
Убедитесь, что у вас есть зависимость spring-webmvc
и commons-fileupload
в вашем файле сборки (например, pom.xml
для Maven):
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.x.x</version> <!-- Убедитесь, что версия соответствует вашей -->
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
Заключение
После выполнения всех вышеперечисленных шагов, ваша форма должна корректно отправлять данные, включая файл, в контроллер. Убедитесь, что корректно обработали объект User
и файл с помощью MultipartFile
. Тестируйте и проверяйте, чтобы убедиться, что все поля правильно заполняются и передаются на сервер.
Применяя вышеуказанные изменения, вы сможете без проблем разрешить многокомпонентное требование в вашем Spring MVC приложении.