정리에 앞서, 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

+ Recent posts