게시판 같은 걸 구현하다 보면 Dto에 담을 데이터를 담은 JSON형태의 문자열과 사진, 동영상 같은 파일을 전송해야 할 경우가 있다. 멀티파트 요청을 사용한다면 한 번의 요청으로 모두 전송할 수 있다.
요청은 기본적으로 POST이다. 헤더의 Content-Type에 multipart/form-data를 넣어준다.
바디의 Key는 서버에서 매칭을 위해 사용할 값이니 원하는 대로 설정하자. Value는 아래처럼 원하는 값이나 파일(여러개도 가능)을 넣어주면 된다. Content-Type도 지정 가능하다.
JSON으로 서버에서 Dto에 요소들을 자동으로 바인딩하고 싶다면 반드시 Content-Type에 application/json을 넣어주자 그렇지 않으면 아래와 비슷한 에러가 발생할 수 있다.
[org.springframework.web.HttpMediaTypeNotSupportedException:
Content-Type 'multipart/form-data;boundary=----WebKitFormBoundaryEnzYm3YGjQtKgLIN' is not supported]
※ 혹시 넣어도 에러가 난다면 Content-Type이 아니라 Description에 추가한 건 아닌지 확인해보자.(경험담 맞음)
테스트를 위한 Dto를 간단하게 만들었다.
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class TestDto {
String text;
String name;
}
JSON은 Dto에 바인딩 후 확인하고, 파일은 따로 처리하는 Controller의 메서드이다. 바인딩이 제대로 되었다면 로그가 정상적으로 출력될 것이고 파일들은 S3에 업로드되게 만들었다. S3를 다루는 방법은 추후에 업로드할 예정이다.
consumes를 쓰지 않으면 required를 설정해도 없으면 에러가 난다.
@RequestPart를 쓰고 있으니 에러가 난다면 확인하자.
@PostMapping(value ="/api/media/upload", consumes = "multipart/form-data")
public ResponseEntity<String> uploadFile
(@RequestPart(value="requestDto") TestDto testDto,
@RequestPart(value = "files",required = false) MultipartFile[] files)
{
try {
log.info(testDto.toString());
if(files!=null)
for(MultipartFile file: files){
log.info(s3Service.saveFile(file));
}
return ResponseEntity.ok("success");
} catch (IOException e) {
log.debug(e.getMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
이 포스트에서는 요청의 사용법과 요소들을 잘 분리되어 처리할 수 있다는 것만 보여줬지만 사용 난이도에 비해 활용도가 높은 도구라고 생각합니다.
'Spring > 개발' 카테고리의 다른 글
[Spring] Port 8080 was already in use. 오류 해결 방법 (0) | 2024.01.18 |
---|