Vuetify + Spring: Как правильно загружать и отображать изображения? - PullRequest
0 голосов
/ 14 февраля 2020

Я загрузил и отобразил изображения с помощью 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>

Вопросы:

  1. Что вы думаете о моем решении?

  2. Здесь я использую RestController для отображения изображений. Я думал, что могу получить изображение напрямую по его расположению на сервере. Без использования RestController для @GetMapping. Например, если мои изображения хранятся в папке с путем /images/companies/logo на сервере, я могу получить свои изображения по URL-адресу с путем http://server/images/companies/logo/namelogo.png

Таким образом, я должен знать имя файла на сервере.

Как отобразить изображение без использования RestController for @GetMapping?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...