I have a problem. I want to convert BufferedImage
to MultipartFile
.
First, on my UI I send a base64
String to the server, and on my server, I convert it to BufferedImage
. After that, I want to convert BufferedImage to MultipartFile and save it on the local storage.
This is my Controller method:
@PostMapping("/saveCategory")
@ResponseStatus(HttpStatus.OK)
public void createCategory(@RequestBody String category) {
BufferedImage image = null;
OutputStream stream;
byte[] imageByte;
try {
BASE64Decoder decoder = new BASE64Decoder();
imageByte = decoder.decodeBuffer(category);
ByteArrayInputStream bis = new ByteArrayInputStream(imageByte);
image = ImageIO.read(bis);
bis.close();
} catch (Exception e) {
e.printStackTrace();
}
String fileName = fileStorageService.storeFile(image);
My storage method:
public String storeFile(MultipartFile file) {
// Normalize file name
String fileName = StringUtils.cleanPath(file.getOriginalFilename());
try {
// Check if the file's name contains invalid characters
if (fileName.contains("..")) {
throw new FileStorageException("Sorry! Filename contains invalid path sequence " + fileName);
}
// Copy file to the target location (Replacing existing file with the same name)
Path targetLocation = this.fileStorageLocation.resolve(fileName);
Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);
return fileName;
} catch (IOException ex) {
System.out.println(ex);
throw new FileStorageException("Could not store file " + fileName + ". Please try again!", ex);
}
}
Such conversion from base64
to MultipartFile
is done by Spring automatically. You just need to use correct annotations.
You can create a wrapper dto
class holding all necessary data.
public class FileUploadDto {
private String category;
private MultipartFile file;
// [...] more fields, getters and setters
}
Then you can use this class in your controller:
@RestController
@RequestMapping("/upload")
public class UploadController {
private static final Logger logger = LoggerFactory.getLogger(UploadController.class);
@PostMapping
public void uploadFile(@ModelAttribute FileUploadDto fileUploadDto) {
logger.info("File upladed, category= {}, fileSize = {} bytes", fileUploadDto.getCategory(), fileUploadDto.getFile().getSize());
}
}
The reason I didn't get the point of the question on a first glance was @RequestBody String category
. I think this is a very very misleading variable name for a file. However, I created the DTO class with the category field aswell so you could include it in your request.
Of course, then you get rid of your controller logic and simply call the service method like fileStorageService.storeFile(fileUploadDto.getFile());
or pass the whole file and make use of category
field.
I also include the request sent from Postman and some console output: