[Spring Boot] 스프링 부트 파일 업로드 다운로드 예제 코드 (깃허브 포함)
스프링 부트 파일 업로드 다운로드
스프링 부트에서의 파일 업로드 다운로드 기능을 하는 코드를 정리한다.
https://doompa.tistory.com/390
우선 위 포스팅 방식대로 기본 환경 설정을 한다.
파일 저장 폴더 생성
src/main → webapp폴더 생성 → upload폴더 생성
앞으로 해당 경로에 파일이 저장될 것이고, 다운로드 시에는 해당 경로에서 파일을 받아 다운로드 하게 될 것이다.
파일 업로드
src/main/java에 ssg.com.a라는 패키지명으로 HelloController를 생성한다.(패키지명을 아무거나 지으면 된다.)
컨트롤러
package ssg.com.a.controller;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import jakarta.servlet.http.HttpServletRequest;
import ssg.com.a.dto.HumanDto;
@RestController
public class HelloController {
//upload
@PostMapping("/fileupload")
public String fileupload(HumanDto human,
@RequestParam("uploadFile") MultipartFile uploadFile,
HttpServletRequest requset) {
System.out.println("HelloController fileupload" + new Date());
System.out.println(human.toString());
//어플리케이션 컨텍스트의 "/upload" 디렉토리의 실제 파일 시스템 경로 얻기
String path = requset.getServletContext().getRealPath("/upload");
//파일 이름 얻기
String filename = uploadFile.getOriginalFilename();
String filepath = path + "/" + filename;
System.out.println("------파일 경로 : " + filepath);
File f = new File(filepath);
//출력 스트림에 대한 버퍼링 기능을 제공하는 클래스
BufferedOutputStream os;
try {
os = new BufferedOutputStream(new FileOutputStream(f));
os.write(uploadFile.getBytes());//업로드된 파일 데이터를 저장
os.close();
} catch (Exception e) {
e.printStackTrace();
return "file upload fail";
}
return "file upload success";
}
//download
}
프론트엔드는 다른 서버에서 실행하도록 구성한다.
dynamic web project로 새 프로젝트 생성 → src/ain/java 에 index.html 생성
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<script src="https://code.jquery.com/jquery-latest.min.js"></script>
<body>
<h3>file upload</h3>
<p id ="result"></p>
<form id="uploadFileFrm">
번호 : <input type="text" name="number"/><br />
이름 : <input type="text" name="name" /><br />
주소 : <input type="text" name="address" /><br /><br />
파일 : <input type="file" name="uploadFile"/><br /><br />
<button type="button" id="uploadBtn">파일 업로드</button>
</form>
<script>
$("#uploadBtn").on("click", ()=>{
$.ajax({
url:"http://localhost:3100/fileupload",
type:"post",
data:new FormData($("#uploadFileFrm")[0]),
enctype:"multipart/form-data",
processData:false,
contentType:false,
cache:false,
success:function(str){
alert("success");
$("#result").text(str);
},
error:function(){
alert("error");
}
})
});
</script>
</body>
</html>
데이터를 넣고 버튼을 누르면 파일 업로드가 됨을 확인할 수 있다. 또한 p 태그 내에 처리 결과가 표시된다.
파일 다운로드
컨트롤러
컨트롤러에 아래의 메서드를 삽입한다.
//download
@Autowired
ServletContext serveletContetxt;
@GetMapping("/fileDownload")
public ResponseEntity<InputStreamResource> filedownload(String filename, HttpServletRequest requset) throws Exception{
System.out.println("HelloController filedownload" + new Date());
//경로
String path = requset.getServletContext().getRealPath("/upload");
//파일의 미디어 타입을 얻는다.
MediaType mediaType = MediaTypeUtiles.getMediaTypeForFileName(serveletContetxt, filename);
System.out.println("file name : " + filename);
System.out.println("mediaType name : " + mediaType);
//파일의 실제경로(파일명 포함된 경로)
File file = new File(path + File.separator + filename);
//FileInputStream : 파일로 부터 바이트 단위로 데이터 읽을 수 있는 InputStram 객체 생성
//InputStreamResource : InputStream 클래스의 래퍼 클래스, InputStream으로부터 데이터를 읽어 클라이언트로 보내는 역할
InputStreamResource is = new InputStreamResource(new FileInputStream(file));
//ResponseEntity : HTTP 응답을 나타내는 객체, HTTP 응답의 상태 코드, 헤더, 본문 등을 세밀하게 제어 가능
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + file.getName())
.contentType(mediaType)
.contentLength(file.length())
.body(is);
}
유틸리티 함수
파일의 데이터 타입을 얻기 위해 아래의 유틸리티 메서드를 이용한다. ssg.com.a(자신의 패키지)에 MediaTypeUtiles라는 클래스를 하나 만들어 스태틱 메서드를 정의한다.
package ssg.com.a;
import org.springframework.http.MediaType;
import jakarta.servlet.ServletContext;
public class MediaTypeUtiles {
public static MediaType getMediaTypeForFileName(ServletContext sc, String filename) {
String mimType = sc.getMimeType(filename);
try {
MediaType mediaType = MediaType.parseMediaType(mimType);
return mediaType;
}catch(Exception e) {
return MediaType.APPLICATION_OCTET_STREAM;
}
}
}
ServletContext
Java Servlet의 인터페이스로서, 웹 애플리케이션의 컨텍스트 정보를 제공하는 객체이다. 리소스 접근, 세션 관리, MIME타입 매핑 등의 기능을 지원한다.
프론트 엔드는 location.href을 통해 데이터를 받아온다. ajax를 통해서는 다운로드 처리가 불가능하다.
$("#downloadBtn").on("click", ()=>{
location.href = "http://localhost:3100/fileDownload?filename=url.txt";
});
url.txt라는 이름의 파일을 받아온다.
또한 하단에 다운로드 창 또한 생성된다.
실제 응답 헤더는 아래의 형태이다.
아래 깃허브는 컨트롤러에 대한 코드이다.
아래 깃허브에서 전체 코드를 확인할 수 있다.
깃허브:
https://github.com/fkthfvk112/springBoot_practice/tree/main/fileUpload_downLoad