RestAPI를 통해 파일을 다운로드 하려면 어떻게 해야할지 알아보겠습니다.
환경
- Spring Boot 3.1.3
- React 18.2.0
- axios 1.4.0
파일 다운로드를 위한 순서
React에서 파일 다운로드 요청
axios를 사용하여 파일 정보를 Spring Boot에 요청합니다.
responseType을 blob으로 설정합니다.
Spring Boot에서 요청 처리
Controller에서 파일 정보를 받아 Service로 전달합니다.
이후 Service에서 처리된 데이터를 리턴시킵니다.
Spring Boot에서 파일 데이터 처리
파일 존재를 확인 후, Resource로 처리하여 리턴합니다.
코드를 통해 확인해 보겠습니다.
React
import { useEffect, useState } from 'react';
import Button from 'react-bootstrap/Button';
import axios from 'axios';
export default function ImageModal(): JSX.Element {
const [info, setInfo] = useState('파일 정보');
async function DownloadFile(){
var tmpUrl = 'http://localhost:8080/file/downloadFile/' + info;
await axios({
method: 'GET',
url: tmpUrl,
responseType: 'blob', // Set the response type to 'blob' to handle binary data
})
.then((response) => {
// 다운로드 위치 설정하는 창 띄워서 다운로드 받게 하는 파트
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', name); // Set the desired filename and extension
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
})
.catch((error) => {
console.error('Error downloading file:', error);
});
}
return (
<div>
<Button variant="primary" onClick={DownloadFile}>
다운로드
</Button>
</div>
);
}
Spring Boot
- SpringBoot는 두 파트로 나뉘어서 코드가 작성되어 있습니다.
- RestAPI를 받는 Controller, 로직을 실행하는 Service로 나뉘어져있습니다.
Controller
package com.myhome.server.api.controller;
import com.myhome.server.api.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourceRegion;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController()
@RequestMapping("/file")
public class FileServerController {
@Autowired
FileServerService service;
@GetMapping("/downloadFile/{info}")
public ResponseEntity<ResourceRegion> streamingPublicVideo(@PathVariable String info){
return service.downloadFile(info);
}
}
- 파일 정보를 받아 서비스로 넘기는 작업을 합니다.
Service
package com.myhome.server.api.service;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourceRegion;
import org.springframework.http.*;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
@Service
public class FileServerPublicServiceImpl implements FileServerPublicService {
@Override
public HttpHeaders getHttpHeader(Path path, String fileName) throws IOException {
String contentType = Files.probeContentType(path); // content type setting
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentDisposition(ContentDisposition
.builder("attachment") //builder type
.filename(fileName)
.build()
);
httpHeaders.add(HttpHeaders.CONTENT_TYPE, contentType);
return httpHeaders;
}
@Override
public ResponseEntity<Resource> downloadFile(String pathStr) {
Path path = Paths.get(pathStr);
try{
HttpHeaders httpHeaders = getHttpHeader(path, path.toFile().getName());
Resource resource = new InputStreamResource(Files.newInputStream(path)); // save file resource
return new ResponseEntity<>(resource, httpHeaders, HttpStatus.OK);
} catch (IOException e) {
return new ResponseEntity<>(null, HttpStatus.OK);
}
return new ResponseEntity<>(null, HttpStatus.OK);
}
}
파일 존재를 확인하고 정보를 불러옵니다.
Path path = Paths.get(pathStr);
헤더를 getHttpHeader함수로 부터 받아오고 Resource타입으로 파일 데이터를 가공합니다.
try{
HttpHeaders httpHeaders = getHttpHeader(path, entity.getName());
Resource resource = new InputStreamResource(Files.newInputStream(path)); // save file resource
return new ResponseEntity<>(resource, httpHeaders, HttpStatus.OK);
} catch (IOException e) {
return new ResponseEntity<>(null, HttpStatus.OK);
}
getHttpHeader에서는 파일 이름과 타입등을 설정하여 헤더값으로 생성합니다.
'개발잡담 > Back-End' 카테고리의 다른 글
CMD로 Django 프로젝트 생성하기 (0) | 2024.07.08 |
---|---|
Spring Boot에서 영상 스트리밍으로 받기 (feat. React) (0) | 2024.02.03 |
Spring batch 5.1.0 간단 사용 (0) | 2024.01.31 |
로그가 필요해 - 서론 (0) | 2023.11.02 |
Spring은 어떻게 여러 개의 요청을 동시에 처리할까? (0) | 2023.09.26 |