Я загрузил и отобразил изображения с помощью Vuetify и Spring. Это работа, но я не уверен, что сделал это правильно. Я не уверен, что реализовал правильный подход к решению этой проблемы. Можете ли вы проверить это и сказать, что вы думаете?
На стороне Vuetify Я использую компонент ввода v-файла и ax ios для отправки изображения на сервер:
<v-file-input
v-model="selectedLogo"
accept="image/png, image/jpeg, image/bmp"
placeholder="Выберите Логотип"
prepend-icon="mdi-camera"
label="Логотип"
show-size
>
<template v-slot:append-outer>
<v-btn small @click="uploadLogo">
<v-icon dense>mdi-upload</v-icon>
</v-btn>
</template>
</v-file-input>
//...
uploadLogo(){
uploadLogo(this.$axios, this.company.id, this.selectedLogo)
}
//...
export const uploadLogo = function ($axios, id, logo) {
let formData = new FormData()
formData.append("logo", logo)
return $axios.post(url+ `/${id}/logo`,
formData,
{
headers: {
'Content-Type': 'multipart/form-data'
}
})
}
Весной У меня есть RestController:
@RestController
@RequestMapping("/api/")
public class FileController {
@Autowired
private FileStorageService fileStorageService;
@PostMapping("companies/{id}/logo")
public ResponseEntity<Object> uploadFile(@PathVariable Long id, @RequestParam("logo") MultipartFile logo) {
String fileName = fileStorageService.uploadLogo(id, logo);
return new ResponseEntity<>(HttpStatus.OK);
}
@GetMapping("/companies/{id}/logo")
public ResponseEntity<Resource> downloadLogo(@PathVariable Long id, HttpServletRequest request) {
Resource resource = fileStorageService.loadLogoAsResource(id);
String contentType = null;
try {
contentType = request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());
} catch (IOException ex) {
contentType = "application/octet-stream";
}
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType(contentType))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
.body(resource);
}
}
fileStorageService:
@Service
public class FileStorageService {
private final Path logoStorageLocation;
@Autowired
public FileStorageService(FileStorageProperties fileStorageProperties) {
this.logoStorageLocation = Paths.get(fileStorageProperties.getLogoDir())
.toAbsolutePath().normalize();
try {
Files.createDirectories(this.logoStorageLocation);
} catch (Exception ex) {
throw new FileStorageException("Could not create the directory where the uploaded files will be stored.", ex);
}
}
public String uploadLogo(Long id, MultipartFile file) {
String fileExtension = StringUtils.getFilenameExtension(file.getOriginalFilename());
String fileName = id.toString() + "." + fileExtension;
try {
if(fileName.contains("..")) {
throw new FileStorageException("Sorry! Filename contains invalid path sequence " + fileName);
}
Path targetLocation = this.logoStorageLocation.resolve(fileName);
Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);
return fileName;
} catch (IOException ex) {
throw new FileStorageException("Could not store file " + fileName + ". Please try again!", ex);
}
}
public Resource loadLogoAsResource(Long id) {
String fileName = id.toString() + ".png";
try {
Path filePath = this.logoStorageLocation.resolve(fileName).normalize();
Resource resource = new UrlResource(filePath.toUri());
if(resource.exists()) {
return resource;
} else {
throw new FileNotFoundException("File not found " + fileName);
}
} catch (MalformedURLException ex) {
throw new FileNotFoundException("File not found " + fileName, ex);
}
}
}
Моя идея заключается в загрузке / отображении изображений по URL http://server/api/companies/{id}/logo
без знания имени файла lo go.
Для отображения я использую компонент v-img:
<v-img :src="'http://localhost:8081/api/companies/' + company.id +'/logo'"></v-img>
Вопросы:
Что вы думаете о моем решении?
Здесь я использую RestController для отображения изображений. Я думал, что могу получить изображение напрямую по его расположению на сервере. Без использования RestController для @GetMapping
. Например, если мои изображения хранятся в папке с путем /images/companies/logo
на сервере, я могу получить свои изображения по URL-адресу с путем http://server/images/companies/logo/namelogo.png
Таким образом, я должен знать имя файла на сервере.
Как отобразить изображение без использования RestController for @GetMapping?