STUDY/Spring
Spring Boot | multipart/form-data 파일 업로드 ( + React , Axios, REST API, multiple files)
개미606
2020. 10. 19. 14:27
클라이언트(React) 측에서 파일과 함께 JSON데이터를 전송해보기.
찾아보면 파일 하나만 전송하는 경우 예제는 많은데 JSON데이터와 함께 보내는 건 잘 없었다..
거기다가 나는 모델 안에 오브젝트들을 다 넣어놔서 복잡한 형태였기 때문에 꼭 JSON형태로 한 번에 보내고 싶었음..
1. FormData로 작성해주기
어딘가에서 받아온 값을.. FormData에 담아준다. FormData에는 키와 값 쌍으로 담아주어야 함.
JSON형태로 바로 보내면 백엔드 서버에서는 알아볼 수 없기 때문에 stringify를 이용해 보내야 한다.
const formData = new FormData();
formData.append("file", data.file);
formData.append(
"key",
new Blob([JSON.stringify(data.info)], { type: "application/json" })
);
*여러 개의 파일을 한 번에 업로드할 경우
동일한 key값으로 여러 번 추가해주면 된다.
data.files.forEach((file) => formData.append("files", file));
2. axios작성
위에서 FormData로 바꿔준 값을 넘겨주고, headers에 Content-Type을 multipart/form-data로 지정해준다.
(X-AUTH-TOKEN은 현재 스프링시큐리티 jwt토큰을 사용해주고 있어서 지정해준 값임)
try {
await axios
.post(`${SERVER_URL}/something/endpoint`, formData, {
headers: {
"X-AUTH-TOKEN": token,
"Content-Type": `multipart/form-data`,
},
})
.then((res) => console.log(res));
} catch (e) {
dispatch({
type: type.WRITE_SALE_POST_FAILURE,
error: e,
});
}
3. Spring Boot 컨트롤러 작성
RequestPart의 value값은 formData에서 지정한 key값과 동일하게 적어주면 된다.
*consumes = { MediaType.APPLICATION_JSON_VALUE, MediaType.MULTIPART_FORM_DATA_VALUE } 생략해도 잘 받아옴
@PostMapping(value="/something/endpoint", consumes = { MediaType.APPLICATION_JSON_VALUE, MediaType.MULTIPART_FORM_DATA_VALUE })
private ResponseEntity<?> insertSalePost(@RequestPart(value="key", required=false) DTO dto,
@RequestPart(value="file", required=true) MultipartFile file) {
logger.info("dto = " + dto);
logger.info("file = " + file);
...생략
}
+) 참고