파일 다운로드 Controller 설명
다음은 파일 다운로드를 처리하는 DownloadController
의 구현 코드입니다. 이 컨트롤러는 파일 ID를 입력받아 해당 파일을 서버에서 다운로드할 수 있도록 응답을 생성합니다.
주요 코드 설명
1. 파일 조회 및 경로 생성
FileInfo fileInfo = fileService.selectFileInfo(fileId);
if(fileInfo == null){
return ResponseEntity.notFound().build();
}
Path path = Paths.get(fileInfo.getFilePath(), fileInfo.getStoredFilename());
Resource resource = new UrlResource(path.toUri());
if(!resource.exists()){
return ResponseEntity.notFound().build();
}
fileService
를 이용해 데이터베이스에서 파일 정보를 조회합니다.- 파일 정보가 없으면
404 Not Found
응답을 반환합니다. - 파일의 저장 경로와 파일명을 이용해 파일의 절대 경로를 생성합니다.
- 해당 경로를
UrlResource
객체로 변환하여 파일 자원으로 사용합니다. - 파일이 존재하지 않을 경우
404 Not Found
를 반환합니다.
2. 파일명 UTF-8 인코딩
String encodedFileName = URLEncoder.encode(fileInfo.getOriginalFilename(), StandardCharsets.UTF_8.toString()).replaceAll("\\+", "%20");
String contentDisposition = "attachment; filename*=UTF-8''" + encodedFileName;
- 파일명을 UTF-8로 인코딩합니다.
URLEncoder.encode
메서드는 공백을+
로 인코딩하므로, 이를%20
으로 변환하여 URL 표준에 맞게 수정합니다.- 인코딩된 파일명을
Content-Disposition
헤더에 추가하여 클라이언트에게 파일명을 명확히 전달합니다. filename*=UTF-8''
형식을 사용하여 UTF-8로 인코딩된 파일명임을 명시합니다.
3. ResponseEntity로 응답 생성
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, contentDisposition)
.body(resource);
- HTTP 응답의 헤더에
Content-Disposition
을 추가하여 파일이 첨부 파일임을 명시합니다. - 파일 내용을
body
에 담아 클라이언트가 다운로드할 수 있도록 합니다.
코드 전체 흐름
@RequestMapping("/Download")
public class DownloadController {
private static String UPLOAD_FOLDER = "D:/logs/";
@Autowired
FileService fileService;
@GetMapping("/{fileId}")
public ResponseEntity<Resource> downloadFile(@PathVariable("fileId") int fileId) throws MalformedURLException, UnsupportedEncodingException {
FileInfo fileInfo = fileService.selectFileInfo(fileId);
if(fileInfo == null){
return ResponseEntity.notFound().build();
}
Path path = Paths.get(fileInfo.getFilePath(), fileInfo.getStoredFilename());
Resource resource = new UrlResource(path.toUri());
if(!resource.exists()){
return ResponseEntity.notFound().build();
}
String encodedFileName = URLEncoder.encode(fileInfo.getOriginalFilename(), StandardCharsets.UTF_8.toString()).replaceAll("\\+", "%20");
String contentDisposition = "attachment; filename*=UTF-8''" + encodedFileName;
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, contentDisposition)
.body(resource);
}
}
주요 포인트
- UTF-8 인코딩: 한글 파일명 등 특수 문자가 포함된 파일명을 정확히 전달하기 위해 사용합니다.
replaceAll("\\+", "%20")
: 공백 문자를 표준 URL 형식에 맞게 변환합니다.Content-Disposition
: 파일 다운로드 시 브라우저가 파일명을 올바르게 인식하도록 설정합니다.