정리에 앞서, Spring Boot에서 file upload 및 download를 위해 작성된 코드는 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
package mul.cam.a.controller;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import mul.cam.a.MediaTypeUtiles;
import mul.cam.a.dto.HumanDto;
@RestController
public class HelloController {
// file upload
@RequestMapping(value = "/fileUpload", method = RequestMethod.POST)
public String fileUpload(HumanDto human,
@RequestParam("uploadFile")
MultipartFile uploadFile,
HttpServletRequest req) {
System.out.println("HelloController fileUpload " + new Date());
System.out.println(human.toString());
// 경로
String path = req.getServletContext().getRealPath("/upload"); // 서버에 업로드
// String path = "c:\temp"; // 폴더에 upload
String filename = uploadFile.getOriginalFilename(); // 기본 파일명
String filepath = path + "/" + filename;
System.out.println(filepath);
File file = new File(filepath);
try {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
bos.write(uploadFile.getBytes());
bos.close();
} catch (Exception e) {
return "file upload fail";
}
return "file upload success";
}
// file download
@Autowired
ServletContext servletContext;
@RequestMapping(value = "/fileDownload")
public ResponseEntity<InputStreamResource> download(String filename, HttpServletRequest req) throws Exception{
System.out.println("HelloController download " + new Date());
// 경로
String path = req.getServletContext().getRealPath("/upload");
MediaType mediaType = MediaTypeUtiles.getMediaTypeForFileName(this.servletContext, filename);
System.out.println("filename: " + filename);
System.out.println("mediaType: " + mediaType);
File file = new File(path + "/" + filename); // filename은 업로드됐을 때의 new filename
// File file = new File(path + File.separator + filename);
InputStreamResource isr = new InputStreamResource(new FileInputStream(file));
// db에서 다운로드 카운트 넣으려면 이 곳에 넣음
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + file.getName()) // file.getName()은 원본 파일명
.contentType(mediaType)
.contentLength(file.length())
.body(isr);
}
}
|
cs |
위 코드에 사용된 static 함수인 getMediaTypeForFileName을 정의한 클래스는
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
package mul.cam.a;
import org.springframework.http.MediaType;
import jakarta.servlet.ServletContext;
public class MediaTypeUtiles {
public static MediaType getMediaTypeForFileName(ServletContext servletContext, String filename) {
String minType = servletContext.getMimeType(filename);
try {
MediaType mediaType = MediaType.parseMediaType(minType);
return mediaType;
} catch (Exception e) {
return MediaType.APPLICATION_OCTET_STREAM;
}
}
}
|
cs |
이제, React 부분을 살펴보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
// Spring Boot의 sample2-file에 맞춰 작성
// npm install axios
import React, {useState} from 'react';
import axios from 'axios';
function App() {
// HumanDto 부분
const [number, setNumber] = useState('');
const [name, setName] = useState('');
const [address, setAddress] = useState('');
const numberChange = (e) => setNumber(e.target.value);
const nameChange = (e) => setName(e.target.value);
const addressChange = (e) => setAddress(e.target.value);
const onSubmit = (e) => {
e.preventDefault(); // 기본 기능과 다르게 만드니까
// alert('onSubmit');
// file + form field -> 짐을 싼다
// /fileUpload 부분에 HumanDto 객체를 참조하는 매개변수를 받는 부분이 있어서 작성하는 것
let formData = new FormData();
formData.append("number", number);
formData.append("name", name);
formData.append("address", address);
// Spring Boot에서 @RequestParam("uploadFile")에 맞춰라
formData.append("uploadFile", document.frm.uploadFile.files[0]);
// 보내자!
axios.post("http://localhost:3000/fileUpload", formData)
.then(res=>{ // success
console.log(res.data);
alert('file upload에 성공했습니다');
})
.catch(function(error){ // error
alert('file upload에 실패했습니다');
});
}
// download
const download = async () => {
let filename = "abc.txt";
// /fileDownload의 매개변수명인 filename에 맞춘다.
const url = "http://localhost:3000/fileDownload?filename=" + filename;
/*
// a tag를 생성하고 자동실행
const download = document.createElement('a'); // <a> 생성
download.setAttribute('href', url);
download.setAttribute('download', filename);
download.setAttribute('type', 'applicaiton/json');
download.click();
*/
// react에서는 window를 붙여줘야 한다.
window.location.href = url;
}
return (
<div>
<h3>file upload</h3>
<form name="frm" onSubmit={onSubmit} encType="multipart/form-data">
<input value={number} onChange={numberChange} placeholder='번호' /><br/>
<input value={name} onChange={nameChange} placeholder='이름' /><br/>
<input value={address} onChange={addressChange} placeholder='주소' /><br/><br/>
<input type='file' name="uploadFile" accept='*' />
<input type="submit" value="file upload" />
</form>
<hr/>
<h3>file download</h3>
<button onClick={download}>file download</button>
</div>
);
}
export default App;
|
cs |
그 결과는
abc.txt라는 파일을 업로드하고, 다운로드 받아보도록 하겠다. (input 태그도 간단하게 입력하고)
끝.
'React' 카테고리의 다른 글
[React] axios (0) | 2023.03.29 |
---|---|
[React] session과 cookie (0) | 2023.03.29 |
[React] hook - useEffect (0) | 2023.03.29 |
[React] hook - useState (0) | 2023.03.29 |
[React] 리액트 시작 및 기초 (0) | 2023.03.29 |