Javascript

[Nuxt + Spring] formData에 image 배열 전송하기

eulBlue 2024. 5. 28. 09:59

📱테스트 환경

"nuxt": "^3.11.2"
"vue": "^3.4.21"
"vue-router": "^4.3.0"
id 'org.springframework.boot' version '3.2.0'
id 'io.spring.dependency-management' version '1.1.4'

 

와 이번건 .. 정말 오래걸렸다 .. :(

일단 화면은 다음과 같은 화면이 있었고 ..

파일 업로드를 누르면 File[] 배열을 서버에 전송해려고 했다.

나는 Nuxt 프론트 작업을 하고 동료 분이 Spring Boots 서버 작업을 해주셨는데

export interface Drive {
  id: number;
  name: string;
  image1: Images;
  image2: Images;
  image3: Images;
  image4: Images;
  image5: Images;
}
const headers: HeadersInit = {
  "Content-Type": "application/json",
};
console.debug(url, headers, body);
const data = await ApiService.fetch<T>(url, {
  method: "POST",
  headers,
  body,
  watch: [watchData],
});

const res = await this.PostFormData("drive", req);

이런형식으로 서버에 데이터를 보내주었다.

이렇게 오전중으로 작업을 끝냈고, 데이터가 나올때까지 쉬고있었는데 ..갑자기 팀장님의 호출로 자리로 호다닥 돌아가보니 ..

내가 저렇게 보낸걸 어떻게든 받아보시려고 노력하시느라 오후를 통채로 삽질을 하셨다 :(

저런식으로 보내면 서버쪽에서 받을 수가 없다 .. multipart/form-data 를 .. ㅠㅠ

json 형식으로 보내면 파일이 커지면 잘릴위험이 커지기 때문에 저렇게 보내면 안되고

multipart/form-data 형식을 사용해야하는데 문제는

Spring 에서는 헤더에 해당 타입을 정해주면 데이터를 받아볼수가없다.

프론트에서는 FormData 형식으로 담아서 보내고서버쪽에서는 @ResponseBody 과 @RequestParam 를 사용해서파일을 통신할 수 있는데 .. 코드는 다음과 같다

async salesDrivSave(req: Drive) {
    try {
      const formData = new FormData();
      formData.append("id", req.id.toString());
      formData.append("name", req.name);
      req.image1.add.forEach((file: File) => {
        formData.append("image1", file);
      });
      req.image2.add.forEach((file: File) => {
        formData.append("image2", file);
      });
      req.image3.add.forEach((file: File) => {
        formData.append("image3", file);
      });
      req.image4.add.forEach((file: File) => {
        formData.append("image4", file);
      });
      req.image5.add.forEach((file: File) => {
        formData.append("image5", file);
      });
	  
      // formData 확인하는 방법
      for (const [key, value] of formData.entries()) {
        console.log(key, value);
      }
      const res = await this.PostFormData("/drive", formData);
      console.log(res);
      return res;
    } catch (e) {
      console.error(e);
    }
  }

통신하는 방식은 자신의 코드에 맞게 사용하면된다.

ㄴㅏ는 Fetch 를 따로 커스텀 정의하여서 불러서 사용하고 있기때문에 맞게 설정하고

req.image4.add 에는 File[] 형식으로 되어있어서 그대로 넣으려고했지만

배열형식은 FormData 에 그대로 집어넣으면 안된다고 한다.

그래서 forEach 를 통해서 이미지를 한땀한땀 넣어주면된다.

Spring Boots 쪽에서는

Getter 쪽에서 해당 변수를 MultipartFile[] 타입으로 지정하고

@ResponseBody
@POST
@RequestParam MultipartFile[] image1

이런식으로 해주면 해당 이미지 배열을 받아볼 수 있다.

ㄴㅏ때문에 삽질한 서버 개발자에게도 좀 미안하고 ..

너무 안일하게 처리해놓은 나에게도 좀 미안하고 ..

이번에는 배운게 좀 많은 시간이였다.