Я реализовал внутренний метод в Spring Boot, позволяющий пользователям создавать сообщения с изображением или без него. Бэкэнд-метод выглядит следующим образом:
@PostMapping(value = "/posts/add", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ResponseStatus(HttpStatus.CREATED)
@ApiResponse(responseCode = "400", description = "Please check the payload or token")
@ApiResponse(responseCode = "200", description = "Post added with image")
@Operation(summary = "Add a new Post with optional image")
@SecurityRequirement(name = "studyeasy-demo-api")
public ResponseEntity addPostWithImage(
@Parameter(content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE)) @RequestPart("caption") PostPayloadDTO postPayloadDTO,
@RequestPart(value = "file", required = false) MultipartFile file,
@RequestParam("postTypeName") String postTypeName,
Authentication authentication) {
try {
// Xác thực email và người dùng
String email = authentication.getName();
Optional optionalAccount = accountService.findByEmail(email);
Users users = optionalAccount.get().getUser();
Post post = new Post();
post.setUser(users);
post.setCaption(postPayloadDTO.getCaption());
PostType postType = postTypeService.getPostTypeByName(postTypeName);
post.setPostType(postType);
postService.save(post);
if (file != null && !file.isEmpty()) {
String contentType = file.getContentType();
if (contentType.equals("image/png") || contentType.equals("image/jpg") || contentType.equals("image/jpeg")) {
String fileName = file.getOriginalFilename();
String generatedString = RandomStringUtils.random(10, true, true);
String finalImageName = generatedString + fileName;
String absoluteFileLocation = AppUtil.get_photo_upload_path(finalImageName, PHOTOS_FOLDER_NAME, post.getPostId());
Path path = Paths.get(absoluteFileLocation);
Files.copy(file.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING);
post.setPostImgURL(absoluteFileLocation); // Lưu đường dẫn ảnh vào post
// Tạo đối tượng Photo và lưu thông tin file vào cơ sở dữ liệu
Photo photo = new Photo();
photo.setName(fileName); // Lưu tên gốc của file
photo.setFileName(finalImageName); // Lưu tên file sau khi thêm chuỗi ngẫu nhiên
photo.setOriginalFileName(fileName); // Lưu tên file gốc
photo.setPost(post); // Liên kết ảnh với album
photoService.save(photo); // Lưu ảnh vào database
} else {
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body("Unsupported file format. Please use PNG, JPG, or JPEG.");
}
}
List photos = new ArrayList();
for (Photo photo : photoService.findByPostId(post.getPostId())) {
String link = "/posts/" + post.getPostId() + "/photos/" + photo.getId() + "/download-photo";
photos.add(new PhotoDTO(photo.getId(), photo.getName(), photo.getDescription(), photo.getFileName(), link));
}
// Lưu post vào database
post = postService.save(post);
PostViewDTO postViewDTO = new PostViewDTO(post.getPostId(), post.getUser().getProfileImage(), post.getCaption(), post.getUser().getUserName(), photos);
return ResponseEntity.ok(postViewDTO);
} catch (Exception e) {
log.debug("Error adding post with image: " + e.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
}
}
Я протестировал серверный API с помощью Postman, и он работает должным образом — как с изображением, так и без него.
Однако, когда я пытаюсь вызываю тот же API из внешнего интерфейса (React), в консоли браузера получаю следующую ошибку:
POST http://localhost:3000/api/v1/posts/add 415 (Unsupported Media Type)
И в журналах серверной части я вижу:
[org.springframework.web.HttpMediaTypeNotSupportedException: Content-Type 'application/octet-stream' is not supported]
Вот соответствующий код из моего интерфейса React:
import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { fetchPostFileUploadWithAuth } from 'client/client';
const Share = () => {
const [file, setFile] = useState(null);
const [description, setDescription] = useState('');
const navigate = useNavigate();
const handleShare = async () => {
const formData = new FormData();
formData.append('caption', description);
formData.append('postTypeName', 'normal');
if (file) {
formData.append('file', file);
}
try {
await fetchPostFileUploadWithAuth('/posts/add', formData);
setDescription('');
setFile(null);
navigate('/');
} catch (error) {
console.error('Failed to create post:', error);
}
};
return (
{/* JSX for file input, caption, etc. */}
);
};
export default Share;
Проблема возникает, когда я пытаюсь загрузить что-либо (с изображением или без него). Внутренний метод правильно настроен на использование multipart/form-data, и я использую FormData во внешнем интерфейсе для отправки запроса.
Я использую метод следующая функция для вызова API:
const fetchPostFileUploadWithAuth = async (uri, formData) => {
const token = localStorage.getItem('token');
const url = `${API_version}${uri}`;
try {
const response = await axios.post(url, formData, {
headers: {
'Content-Type': 'multipart/form-data',
"Authorization": `Bearer ${token}`,
},
});
return response;
} catch (error) {
// Handle errors if the request fails
console.error('Error fetching data:', error);
}
};
Подробнее здесь: https://stackoverflow.com/questions/791 ... ith-an-ima
«Как исправить ошибку «415 Неподдерживаемый тип носителя» при загрузке сообщения с изображением с использованием бэкэнда ⇐ JAVA
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение