[Front-End Side] Axios POST를 이용해 File 업로드 요청
1. 파일을 주고받을 때는 Multipart/form-data 타입을 이용한다.
1.1. HTTP Headers에 타입 추가
아래와 같이 headers에 'multipart/form-data'를 추가한다.
axios({
...
headers: {
'Content-Type': 'multipart/form-data',
},
});
1.2. JavaScript의 FormData 객체를 생성해 데이터로 전달한다.
FormData 인터페이스는 Key/Value 쌍으로 데이터를 쉽게 생성/삭제할 수 있는 방법을 제공한다.
★중요★
하나의 Key에 Value를 'List 형태'로 여러 개를 보내고 싶을땐 동일한 Key에다 계속 append 해준다. Java에서는 List<Type>과 Mapping 된다.
const formData = new FormData();
formData.append('inputFile', file1); // File 타입 객체 첨부
formData.append('inputStr', str); // String 같은 타입도 첨부 가능
// ★중요★ 하나의 Key(inputFileList)에 List 형태로 여러 개의 value 전달 가능
formData.append('inputFileList', file2);
formData.append('inputFileList', file3);
formData.append('inputFileList', file4);
[Reference] MDN Web Docs - JavaScript FormData 인터페이스
https://developer.mozilla.org/ko/docs/Web/API/FormData
2. 완성된 Axios POST 요청 Code
const saveFileRequest = () => {
const formData = new FormData();
formData.append('inputFile', fileObject1); // File 타입 객체 첨부
formData.append('inputStr', strObject); // String 타입 첨부
// ★중요★ 하나의 Key(inputFileList)에 List 형태로 여러 개의 value 전달 가능
formData.append('inputFileList', fileObject2);
formData.append('inputFileList', fileObject3);
formData.append('inputFileList', fileObject4);
axios({
method: 'post',
url: 'http://localhost:8080/file-import',
headers: {
'Content-Type': 'multipart/form-data',
},
data: formData,
}).then(response => {...});
};
[주의] Axios의 data에는 FormData 객체를 그대로 전달한다
처음에 헤매면서 시간 낭비를 한 부분이다. 아래와 같이 작성하지 않도록 주의하자!
잘못된 예시 1) JSX 문법으로 착각
axios({
...
data: {formData},
}};
잘못된 예시 2) Object의 Key와 @RequestParam이Mapping 된다고 착각 (★특히 오랫동안 헤맸던 부분★)
axios({
...
data: {inputFile: formData} // "inputFile"을 Spring의 RequestParam("inputFile")과 Mapping된다고 착각
}};
[참고] Axios의 headers 자동 생성
axios의 data 속성에 전달되는 객체가 FormData일 경우 headers에 'Content-Type': 'multipart/form-data'를 명시하지 않아도 자동으로 추가한다
[Back-End Side] @RequestParam, MultipartFile 인터페이스로 Mapping
@PostMapping(
value = "/file-import",
consumes = MediaType.MULTIPART_FORM_DATA_VALUE
)
public void saveScenarioFile(@RequestParam("inputFile") MultipartFile file,
@RequestParam("inputStr") String str),
@RequestParam("inputFileList") List<MultipartFile> fileList) {
...
}
- consumes
들어오는 데이터 타입을 강제할 때 사용된다. 즉, 위에 작성된 consumes 부분은 Multipart form-data로 강제하는 것을 볼 수 있다. 따라서 HTTP headers의 'Content-Type'에 명시되지 않으면 에러가 발생한다. 강제할 때 사용하는 것이므로 제거해도 정상적으로 작동한다. - @RequestParam("Key")와 FormData 객체의 Key Mapping
[2. 완성된 Axios POST 요청 Code] 코드에서 formData에 데이터를 추가할 때 Key/Value 쌍으로 추가했다. 이 때 추가한 Key - inputFile, inputStr를 @RequestParam("inputFile"), @RequestParam("inputStr")과 같이 작성해 Mapping 시킨다 - MultipartFile
Front-End에서 전달받을 File은 MultipartFile 인터페이스 타입으로 받는다.
[참고] MultipartFile 객체 파일을 서버 PC에 쉽게 저장하기
MultipartFile 객체는 객체에 담긴 데이터를 Java의 File로 쉽게 converting 해주는 trasferTo() 메서드를 제공한다. 아래와 같이 코드를 작성하면 PC에 파일이 생성된다.
public void saveScenarioFile(@RequestParam("inputFile") MultipartFile file,
@RequestParam("inputStr") String str),
@RequestParam("inputFileList") List<MultipartFile> fileList) {
try {
File file = new File("원하는 디렉토리 경로" + inputFile.getOriginalFilename());
inputFile.transferTo(file);
} catch (IOException e) {
e.printStackTrace();
}
}
[References]Spring에서 MultipartFile 타입을 받는 세 가지 방법(읽어보기)
https://caileb.tistory.com/152
consumes, produces
https://mungto.tistory.com/438
MultipartFile to File
https://kkumalog.tistory.com/74
'Back-End > Spring' 카테고리의 다른 글
[Spring] Annotation을 이용한 DI (2) @AutoWired와 @Qualifier (0) | 2022.02.02 |
---|---|
[Spring] Annotation을 이용한 DI (1) @Component, @AutoWired (0) | 2022.01.17 |
[Spring] Collection Bean 생성하기 - XML Config (0) | 2021.12.14 |
[Spring] IoC 컨테이너 사용하기 - XML Config (0) | 2021.08.19 |
[Spring] 값(Value) 주입 설정 방법 - XML Config (0) | 2021.07.24 |