Как обмениваться изображениями между React и Spring
Я разрабатываю фулл-стек интернет-магазин и мне нужно с реакта передавать изображение на мой Spring Rest Controller. Как мне это сделать? Я попытался сделать что-то типо того:
setFile(e.target.files && e.target.files[0])
Это файл из <input type="file"/>
После этого я отправляю файл в put-методе
DishesService.addDish(dish, file)
static async addDish(dish: IDish, file: any) {
try {
await axios.post<IDish>('http://localhost:8080/dishes', dish)
.then(response => {
this.updateDishImage(response.data.id, file)
})
} catch (e) {
console.log('произошла ошибка при добавлении блюда')
}
}
static async updateDishImage(id: number | undefined, image: any) {
try {
await axios.put('http://localhost:8080/dishes/' + id, {}, {
params: {
file: image
}
})
} catch (e) {
console.log('Произошла ошибка при добавлении картинки к блюду')
}
}
И мой put-метод в контроллере Spring:
@PutMapping("{dishId}")
public ResponseEntity<DishEntity> updateDishImage(@PathVariable Long dishId, @RequestParam("file") MultipartFile file) {
DishEntity updateDish = dishService.updateDishImage(file, dishId);
return ResponseEntity.ok(updateDish);
}
Я получаю ошибку:
org.springframework.web.multipart.MultipartException: Current request is not a multipart request
Ответы (1 шт):
Насколько я вижу, проблема в том, как вы с фронта подготавливаете и отправляете запрос.
await axios.put('http://localhost:8080/dishes/' + id, {}, {
params: {
file: image
}
})
Content-Type
Начнем с того, что вы не указываете Content-Type запроса.
По умолчанию будет использоваться
Content-Type=application/x-www-form-urlencoded
При этом в контроллере Вы пытаетесь получить MultipartFile file, который подразумевает запрос типа multipart/form-data
Передача данных
Вы передаете данные, через params(параметры запроса).
Это значит что параметры
{
param1: "value1",
param2: "value2",
param3: "value3"
}
будут преобразованы в строку
param1=value1¶m2=value2¶m3=value3
и будут добавлены в адресную строку
http://localhost:8080/dishes/{id}?param1=value1¶m2=value2¶m3=value3
и в таком виде запрос уйдёт на сервер.
И это точно не наш вариант!
Для того, чтобы данные дошли до сервера их следует передавать в data
Что нужно делать
- Указываем заголовок с корректным
Content-Type - Собирваем данные и передаем их через
data
await axios({
method: "put",
url: 'http://localhost:8080/dishes/' + id,
// в data передаем объект с данными формы
data: {
file: file,
// ... при необходимости указываем другие поля формы
},
headers: { "Content-Type": "multipart/form-data" }, // указываем Content-Type
});