개발 관련 학습 및 문제해결

[ Frontend / React ] multipartFile을 다른 속성값과 객체에 넣어 전달해주려고 할 때 1

날파리1 2022. 12. 27. 15:19

이전 S3 파일 프론트엔드 코드 작성시 아래와 같이 하면 된다고 했는데 이는 하나의 이미지, 녹음 파일등을 업로드할 때에만 적용된다.

프론트엔드에서

1. formdata 선언

2. input 타입을 file 형태로 한 후  녹음파일만 올리도록 할 것이면 accept를 아래와 같이 제한

3. onChange 함수로 아래처럼 받아줌 e.target.files[0] 과 formData.append 해주는 것이 포인트!

4. 받아온 formData를 백엔드로 그대로 전달해줄 것. 

const formData = new FormData();

const handleChangeRecord = (e) => {
    const record = e.target.files[0];

   formData.append('multipartFile', record);
   practicalTemplatesAdminFormStore.changeRecord(formData);
  };
  
	
	<div>
            <label htmlFor="input-record">녹음파일</label>
            <input
              id="input-record"
              type="file"
              name="record"
              accept="audio/*"
              onChange={handleChangeRecord}
            />
     </div>
 

[SPRING BOOT, Java] AWS S3 이미지 및 녹음 파일 올리기

AWS S3를 통해 업로드하는 법을 검색하면 수많은 글들이 나오지만 Spring Boot 에 관련해서는 적당한 글이 없어서 한 번 자세히 써보고자 한다. 1. 세팅 및 전제조건 1. 우선 이것은 I AM 과 S3 서버를 세

onulmansanda.tistory.com

 

1. Page 에서는 위와 같이 작성해준다. + 추가로 다른 속성을 담은 객체를 만들어준다.

본인은 아래처럼 스토어에 각각의 정보를 담을 코드를 추가로 만들어 주었다.

const handleSubmitSpeakPracticeForm = async (event) => {
    event.preventDefault();

    if (practiceForm.title === '' || practiceForm.situation === '' || practiceForm.englishScript === ''
     || practiceForm.koreanScript === ''
    || record === '') {
      return;
    }

    await speakPracticesStore.createPractice();
    speakPracticesStore.clearPracticeTemplate();

    navigate('/speak');
  };
<div>
            <label htmlFor="input-title">제목</label>
            <Input
              id="input-title"
              name="title"
              value={practiceForm.title}
              onChange={(e) => speakPracticesStore.changeTitle(e.target.value)}
            />
          </div>
          <div>
            <label htmlFor="input-situation">상황설명</label>
            <EditTextArea
              id="input-situation"
              name="situation"
              value={practiceForm.situation}
              onChange={(e) => speakPracticesStore.changeSituation(e.target.value)}
            />
          </div>
          <div>
            <label htmlFor="input-englishScript">영어로 써보기</label>
            <EditTextArea
              id="input-englishScript"
              name="englishScript"
              value={practiceForm.englishScript}
              onChange={(e) => speakPracticesStore.changeEnglishScript(e.target.value)}
            />
          </div>
          <div>
            <label htmlFor="input-koreanScript">한글로 상황설명 해보기</label>
            <EditTextArea
              id="input-koreanScript"
              name="koreanScript"
              value={practiceForm.koreanScript}
              onChange={(e) => speakPracticesStore.changeKoreanScript(e.target.value)}
            />
          </div>

2. Store에서 파일과 다른 정보를 담은 객체를 ApiService로 보내준다.

async createPractice() {
    await speakPracticesApiService.createPractice(this.practiceForm, this.record);

    this.publish();
  }

 

3. Store에서 파일과 다른 정보를 담은 객체를 ApiService로 보내준다.

* 보내줄 때 아래처럼 append 한 formdata 파일에(위에서 보내준 record 라는 파일을 이해하기 쉽게 formData로 바꾸어서 받아주었다.)

다른정보를 담은 객체를 append 하여 넣어준다.  

formData.append( '백엔드에서 전달받고싶은 객체 이름', JSON.stringify(전달할 객체));

 

headers : {

'Content-Type': 'multipart/form-data',

}

async createPractice(practiceForm, formData) {
    const url = `${baseUrl}/practice/new`;

    const {
      title, situation, englishScript, koreanScript,
    } = practiceForm;

    formData.append('practice', JSON.stringify(practiceForm));

    const { data } = await axios.post(url, formData, {
      headers: {
        'Content-Type': 'multipart/form-data',
      },
    });

    return {
      id: data.id,
      title: data.title,
      situation: data.situation,
      englishScript: data.englishScript,
      koreanScript: data.koreanScript,
      recordUrl: data.recordUrl,
    };
  }