본문 바로가기

Backend/Spring

Spring Boot 파일 다운로드 (Controller)

스프링부트에서 컨트롤러를 만들어서 이미지를 다운로드하는 코드에요.

부트 환경이 아니여도 스프링 프레임워크를 사용하고 있다면 어디에나 적용 가능합니다.

 

코드를 간단하게 설명드리자면

파일 데이터에서 직접 Content-Type을 조사하여 Response Header에 세팅하고

InputStream으로 Resource를 생성하고 body에 세팅하여 전송합니다.

Content-Disposition 값을 inline으로 하거나 헤더를 설정하지 않으면 웹 브라우저 내에서 이미지 확인이 가능합니다.

(default가 inline)

 

@GetMapping("download")
public ResponseEntity<Resource> download() throws IOException {
	Path path = Paths.get("C:/Users/001/Pictures/anise-4623554_1280.png");
	String contentType = Files.probeContentType(path);
	
	HttpHeaders headers = new HttpHeaders();
	headers.add(HttpHeaders.CONTENT_TYPE, contentType);

	Resource resource = new InputStreamResource(Files.newInputStream(path));
	return new ResponseEntity<>(resource, headers, HttpStatus.OK);
}

 

크롬 브라우저에서 호출해보면 이미지가 화면 상에 제대로 나오는 것을 확인할 수 있어요.

 

 

자 그럼 위의 코드에서 Content-Disposition 값을 attachment로 변경해볼게요.

Content-Disposition 헤더는 HTTP 표준이 아니지만 널리 사용되어 HTTP 스펙 문서에 포함되었어요.

아래 코드는 한글 이름도 깨지지 않고 정상적으로 출력이 될 거에요.

그리고 동일하게 브라우저에서 URL을 호출해보세요.

 

headers.setContentDisposition(ContentDisposition.builder("attachment")
        .filename("anise-4623554_1280.png", StandardCharsets.UTF_8)
        .build())

 

사실, 파일을 누구에게나 공개하고 빠르게 응답해야 하는 시스템에서는 직접 WAS에서 다운로드할 필요는 없습니다. (요구사항에 따라 다르겠지만...)

WAS에서 파일 다운로드를 구현할 때에는 보안이 필요한 파일을 다루는 경우가 많고, 파일명을 파라미터로 받아서 접근하는 경우도 있죠.

이 때 클라이언트에서 파일명에 경로도 넣고 이름도 임의로 조작하여 다른 서버 파일에 마음대로 접근할 수 있음을 인지하고 계셔야 합니다.

파일에 철저한 보안이 필요하다면 경로 문자열을 직접 서버에서 관리하고 파일에 대한 권한 기능을 도입해야 합니다.