Search
Duplicate

[스프링 게시판] 파일 다운로드

@3/22/2023
postView 시 파일 list 출력
each로 파일 목록 출력 - 파일 id로 url 매핑
url: /files/{fileId}

첨부파일 리스트 출력

<!-- 첨부파일 목록 --> <div th:if="${post.uploadFiles.size() > 0}" class="row d-flex flex-column"> <button class="col-3 me-auto btn btn-outline-primary" type="button" data-bs-toggle="collapse" data-bs-target="#collapseExample"> <small>첨부파일 보기</small> </button> <div th:each="uploadFile : ${post.uploadFiles}" class="col-3 me-auto collapse p-0" id="collapseExample"> <div class="list-group"> <a th:href="|/files/${uploadFile.id}|" class="list-group-item list-group-item-action"> <div class="d-flex justify-content-between"> <span class="overflow-scroll align-bottom" th:text="${uploadFile.originalFileName}" style="font-size: 12px;">첨부파일 이름</span> <small th:text="${uploadFile.size}" class="text-muted ms-2" style="font-size: 10px;">3MB</small> </div> </a> </div> </div> </div>
Java
복사
파일 id를 통해 다운로드할 수 있도록 함(다운로드 권한 등을 추후 기능을 가정)
UploadFile 엔티티에 사이즈 및 표기용 사이즈 추가
package dev.gyuray.forum.domain; import lombok.EqualsAndHashCode; import lombok.Getter; import javax.persistence.*; @Entity @Getter @EqualsAndHashCode public class UploadFile { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String originalFileName; private String storedFileName; private String size; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "post_id") private Post post; public UploadFile() { } public UploadFile(String originalFileName, String storedFileName, long size) { this.originalFileName = originalFileName; this.storedFileName = storedFileName; this.size = formattedSize(size); } public void addToPost(Post post) { this.post = post; post.getUploadFiles().add(this); } public String formattedSize(Long size) { double digits = Math.log10(size); if (digits < 3) { return size + "B"; } else if (digits < 6) { return size / 1_000 + "KB"; } else { return size / 1_000_000 + "MB"; } } }
Java
복사
결과 화면

파일 다운로드 컨트롤러

package dev.gyuray.forum.controller; import dev.gyuray.forum.domain.UploadFile; import dev.gyuray.forum.repository.post.UploadFileRepository; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.Resource; import org.springframework.core.io.UrlResource; import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.util.UriUtils; import java.net.MalformedURLException; import java.nio.charset.StandardCharsets; @Controller @RequiredArgsConstructor @RequestMapping("/files") public class FileController { private final UploadFileRepository uploadFileRepository; @Value("${file.path}") private String filePath; @GetMapping("/{uploadFileId}") public ResponseEntity<Resource> downloadFile( @PathVariable Long uploadFileId ) throws MalformedURLException { UploadFile uploadFile = uploadFileRepository.findOne(uploadFileId).orElseThrow(() -> { throw new IllegalArgumentException("해당 파일이 존재하지 않습니다."); }); String storedFileName = uploadFile.getStoredFileName(); String originalFileName = uploadFile.getOriginalFileName(); UrlResource resource = new UrlResource("file:" + filePath + storedFileName); String encodedOriginalFileName = UriUtils.encode(originalFileName, StandardCharsets.UTF_8); String contentDisposition = "attachment; filename=\"" + encodedOriginalFileName + "\""; return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, contentDisposition) .body(resource); } }
Java
복사

결과 화면

관련 커밋

5191e7036b9ddc46bb3bd8363f4b1b07f051664c
commit