개발공부/React

[React + Spring] axios.postForm()으로 폼 데이터 전송하기

jnnjnn 2024. 5. 28. 17:52

 

axios.postForm

 

React와 Spring은 응답/요청하는 과정에서 데이터를 JSON 형식으로 전달하기 때문에 파일을 전송하려면 파일 업로드시 form 데이터 형식으로 보내야 합니다

 

일반 post 요청으로 보낼 경우 form 데이터 형식으로 전달하려면 다음과 같이 config에 타입을 명시해서 보내야 합니다

axios.post(`/api/board/write`, {
    headers: {
      'Content-type': 'multipart/form-data',
    },
    title : '제목',
    content : '내용'
    files : files
  });

 

 

post() 메서드 대신 axios.postForm() 메서드를 사용하면  config를 따로 작성할 필요 없이  form 데이터 형식을 전송할 수 있습니다

 

axios.postForm("/api/board/add", { title, content, files })

 

 

헤더에서 데이터 타입이 변경되어서 전송되는 것을 확인할 수 있습니다.

 

 

예제

const [files, setFiles] = useState([]);
<Box>
  <FormControl>
    <FormLabel>파일 첨부</FormLabel>
    <Input
      type={"file"}
      accept={"image/*"}
      multiple
      onChange={(e) => {
        setFiles(e.target.files);
      }}
    />
    <FormHelperText>
      총 용량은 10MB, 한 파일은 1MB를 초과할 수 없습니다
    </FormHelperText>
  </FormControl>
</Box>
<Box>
  <Button onClick={handleSaveClick}>
    저장
  </Button>
</Box>

 

useState()를 사용해 files의 값을 관리하고 Input에 입력된 파일을 files에 저장합니다

function handleSaveClick() {
    axios
      .postForm("/api/board/add", { title : "제목" , content : "내용" , files })
  }

 

[저장] 버튼을 클릭하면 axios.postForm() 요청을 보냅니다

 

@PostMapping("/api/board/add")
public ResponseEntity add(
    String title, 
    String content, 
    @RequestParam(value = "files[]") MultipartFile[] files) throws IOException {
    
    service.add(title, content, files);
    
    return ResponseEntity.ok().build();
}

 

요청한 경로의 Spring 컨트롤러에서 값을 받아 service에 보냅니다.

이때 데이터는 modelAttribute 형태로 전달이 되므로 @RequestParam으로 값을 받아 처리합니다.

파일이 중복 선택되는 것을 선택했으므로 (Input 태그의 mutiple) 전달한 date명 뒤에 [] 배열 표시가 붙어 전달받게 됩니다

 

service에서 파일을 저장하기 위해 transferTo()를 사용했으므로 checked exception 처리를 해줍니다

 

public void add(String title, String content, MultipartFile[] files) throws IOException {

    	mapper.insert(title, content);

        for (MultipartFile file : files) {
            mapper.insertFileName( file.getOriginalFilename());

            // 실제 파일 저장
            // 부모 디렉토리 만들기
            String dir = STR."C:/Temp/prj2/\{board.getId()}";
            File dirFile = new File(dir);
            if (!dirFile.exists()) {
                dirFile.mkdirs();
            }

            // 파일 경로
            String path = STR."C:/Temp/prj2/\{board.getId()}/\{file.getOriginalFilename()}";
            File destination = new File(path);
            file.transferTo(destination);
        }
    }

 

mapper 인터페이스를 사용해서 파일 이름을 데이터베이스에 저장하고 File 객체를 사용해 로컬에도 저장합니다.

 

mapper 인터페이스는 생략하였습니다