본문 바로가기
Framework & Library/Spring Boot

[Spring Boot] : 파일 업로드, 파일 다운로드 구현하기

by 오주현 2022. 3. 18.
반응형

파일 업로드와 파일 다운로드를 구현해 봤다.

private String uploadFileName;
private String storeFileName;

public UploadFile(String uploadFileName, String storeFileName) {
    this.uploadFileName = uploadFileName;
    this.storeFileName = storeFileName;

uploadFileName는 고객이 업로드한 파일명이다.

storeFileName는 서버 내부에서 관리하는 파일명이다.

서로 다른 고객이 같은 파일을 업로드할 때 충돌날 수 있어서 서버에는 이름이 겹치지 않게 저장해야 한다. 때문에 파일명을 분리했다.

 

@Value("${file.dir}")
private String fileDir;

파일 위치를 가져온다.

 

private String createStoreFileName(String originalFilename) {
    String ext = extractExt(originalFilename);
    String uuid = UUID.randomUUID().toString();
    return uuid + "." + ext;
}

UUID를 사용해서 서버 내부에서 관리하는 파일명이 겹치지 않도록 한다.

 

private String extractExt(String originalFilename) {
    int pos = originalFilename.lastIndexOf(".");
    return originalFilename.substring(pos + 1);
}

extractExt()를 통해 서버 내부에서 관리하는 파일명에도 확장자를 추출해 붙여준다.

 

public String saveItem(@ModelAttribute ItemForm itemForm, RedirectAttributes redirectAttributes) throws IOException {
        UploadFile attachFile = fileStore.storeFile(itemForm.getAttachFile());
        List<UploadFile> storeFiles = fileStore.storeFiles(itemForm.getImageFiles());

        //데이터베이스에 저장
        Item item = new Item();
        item.setItemName(itemForm.getItemName());
        item.setAttachFile(attachFile);
        item.setImageFiles(storeFiles);
        itemRepository.save(item);

        redirectAttributes.addAttribute("itemId", item.getId());
				return "redirect:/items/{itemId}";

폼 데이터를 저장하고 보여주는 화면으로 리다이렉트를 한다.

 

@ResponseBody
@GetMapping("/images/{filename}")
public Resource downloadImage(@PathVariable String filename) throws MalformedURLException {
    return new UrlResource("file:" + fileStore.getFullPath(filename));
}

img태그로 이미지를 조회할 때 사용된다. UrlResource로 이미지 파일을 읽어서 @Response로 이미지 바이너리를 반환한다.

 

public ResponseEntity<Resource> downloadAttach(@PathVariable Long itemId) throws MalformedURLException {
        Item item = itemRepository.findById(itemId);
        String storeFileName = item.getAttachFile().getStoreFileName();
        String uploadFileName = item.getAttachFile().getUploadFileName();

        UrlResource resource = new UrlResource("file:" + fileStore.getFullPath(storeFileName));

        log.info("uploadFileName={}", uploadFileName);

        String encodeUploadFileName = UriUtils.encode(uploadFileName, StandardCharsets.UTF_8);
        String contentDisposition = "attachment; filename=\\"" + encodeUploadFileName + "\\"";

        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, contentDisposition)
                .body(resource);

 

파일을 다운로드할 때 실행된다. 파일 다운로드시 고객이 업로드한 파일명으로 다운로드하게 하는 게 좋은데 Content-Disposition 해더에 attachment; filename=”업로드 파일명”값을 주면 된다고 한다.

 

multiple="multiple"

HTML에서 위 옵션을 주어 파일을 여러개 올릴 수 있게 했다.

private List<MultipartFile> imageFiles; 이 코드로 여러 파일을 받을 수 있다.

 

이렇게 마지막 실습 코딩도 완료하고 MVC 2편 강의도 완강했다.


스프링 MVC 2편 - 백엔드 웹 개발 활용 기술을 참고하여 공부하였습니다.

반응형

댓글