반응형
오늘은 Spring Boot RESTful API를 사용하여 서버에 저장된 파일을 클라이언트로 다운로드하는 방법을 알아보겠습니다. 파일 다운로드는 보고서나 이미지, 문서 등을 사용자에게 제공할 때 주로 사용됩니다.
1. 파일 다운로드를 위한 기본 설정
(1) 파일 저장 디렉토리 설정
application.properties에 이미 설정된 파일 저장 경로를 기반으로 파일을 다운로드합니다. 아래 설정은 동일합니다.
file.upload-dir=uploads/
2. 파일 다운로드 API 구현
(1) Controller 작성
ResponseEntity를 사용하여 파일을 클라이언트에 전송합니다.
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.web.bind.annotation.*;
import java.net.MalformedURLException;
import java.nio.file.Path;
import java.nio.file.Paths;
@RestController
@RequestMapping("/api/files")
public class FileDownloadController {
@Value("${file.upload-dir}")
private String uploadDir;
@GetMapping("/download/{filename}")
public ResponseEntity<Resource> downloadFile(@PathVariable String filename) {
try {
// 파일 경로 설정
Path filePath = Paths.get(uploadDir).resolve(filename).normalize();
Resource resource = new UrlResource(filePath.toUri());
if (!resource.exists()) {
return ResponseEntity.notFound().build();
}
// 파일 다운로드 헤더 설정
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
.body(resource);
} catch (MalformedURLException e) {
return ResponseEntity.badRequest().build();
}
}
}
3. 파일 다운로드 API 테스트
(1) Postman으로 테스트
- Endpoint: GET /api/files/download/{filename}
- Headers: 필요 없음
- Response: 서버에 저장된 파일이 다운로드됩니다.
(2) 브라우저에서 테스트
URL에 http://localhost:8080/api/files/download/example.txt와 같이 직접 접근하면 브라우저에서 파일이 다운로드됩니다.
4. 예외 처리
파일이 존재하지 않거나 접근할 수 없는 경우를 대비하여 적절한 예외 처리를 추가합니다.
if (!resource.exists() || !resource.isReadable()) {
return ResponseEntity.notFound().build();
}
5. 파일 접근 보안 강화
파일 접근 경로를 제한하여 서버 파일 시스템의 보안을 강화합니다. 사용자가 다운로드 요청 시 경로 탐색 공격을 시도할 수 있으므로 normalize()를 호출해 경로를 정규화합니다.
Path filePath = Paths.get(uploadDir).resolve(filename).normalize();
(1) 파일 확장자 검증
허용된 파일 확장자만 다운로드 가능하도록 검증합니다.
private boolean isValidFileType(String filename) {
String[] allowedExtensions = {"jpg", "png", "pdf", "txt"};
String fileExtension = filename.substring(filename.lastIndexOf(".") + 1);
for (String extension : allowedExtensions) {
if (extension.equalsIgnoreCase(fileExtension)) {
return true;
}
}
return false;
}
컨트롤러에서 파일 검증 로직을 추가합니다.
if (!isValidFileType(filename)) {
return ResponseEntity.badRequest().body(null);
}
6. 클라이언트의 파일 저장
파일 다운로드 시 브라우저 또는 클라이언트는 attachment 헤더에 설정된 파일명을 사용하여 파일을 저장합니다. 이를 통해 원본 파일명을 유지할 수 있습니다.
7. 파일 업로드 및 다운로드 통합 테스트
(1) 업로드 후 다운로드 테스트
- 업로드 API(/api/files/upload)로 파일을 업로드합니다.
- 다운로드 API(/api/files/download/{filename})로 업로드된 파일을 다운로드합니다.
- 다운로드된 파일의 내용을 확인하여 정확성을 검증합니다.
실습 결과
파일 업로드와 다운로드 기능을 모두 구현하였으며, 적절한 예외 처리와 보안 조치를 통해 안정적인 RESTful API를 완성할 수 있습니다.
반응형
'개발 > 전자정부프레임워크' 카테고리의 다른 글
Spring Boot에서 트랜잭션 관리하기 (3) | 2024.12.29 |
---|---|
데이터베이스 연결 풀 설정과 HikariCP 사용 (0) | 2024.12.29 |
RESTful API에 파일 업로드 구현하기 (0) | 2024.12.29 |
Spring Boot에 데이터 검증 (Validation) 적용하기 (0) | 2024.12.28 |
RESTful API에 CORS 설정 적용하기 (0) | 2024.12.28 |