Vue + Spring Boot으로 파일과 DTO 함께 REST 통신하기
Spring Boot Controller 부분
@PostMapping(value = "", consumes = {"multipart/form-data"})
public ResponseEntity<? extends BaseResponseBody> createRoom(
@RequestPart(value = "thumbnail", required = false) MultipartFile thumbnail,
@RequestPart(value = "room", required = true) RoomCreatePostReq req) {
...
}
- @PostMapping 어노테이션 인자 중
consumes
를{"multipart/form-data"}
로 설정 - file(MultipartFile)과 DTO를 인자로 받기 위해
@RequestPart
어노테이션 사용 - 이때 프론트에서 FormData() 객체 보내줄 때 key로 @RequestPart에서 설정한 value를 잘 설정해야함
Vue Axios 부분
const createRoom = () => {
var thumbnailImg = document.getElementById("thumbnail").files[0]
const room = {
capacity: state.capacity,
description: state.description,
password: state.password,
title: state.title,
}
const roomData = new FormData()
roomData.append("thumbnail", thumbnailImg)
roomData.append("room", new Blob([JSON.stringify(room)] , {type: "application/json"}))
store.dispatch('root/createRoom', roomData)
.then(() => {
console.log('요청은 성공')
// router.push({ name: 'ConferenceDetail' })
})
.catch((err) => {
console.log('실패')
console.log(err)
})
}
- file을 받는 input 태그 자체를 getElementById()로 받아와서 파일 배열의 첫번째 파일로 인덱싱하고 이를 파일 변수로 저장
- room 객체는 new Blob()안에
JSON.stringify()
을 통해 JSON 형식으로 변환한 뒤, type을 application/json 으로 설정 - FormData() 객체에 file과 room 을 백엔드 @RequestPart에서 설정한 value를 잘!! 설정하고 append 해야함
- store.dispatch(‘root/createRoom’, roomData) 에서 두번째 매개변수로 FormData 객체 넘겨줄 때 { } 로 감싸지 말고 자기 자신을 그대로 넘겨줘야함
- axios 보낼 때 header에 ‘Content-Type’:‘multipart/form-data’로 설정