문제
진행 중인 프로젝트에서
이미지 파일(MultipartFile) 과 일반 데이터(JSON) 를 동시에 전송받는 API를 개발해야 했다.
하지만 다음과 같은 오류가 발생했다...
Resolved [org.springframework.web.bind.MissingServletRequestPartException: Required request part 'file' is not present]
/* 또는 */
Content type 'application/json' not supported
원인
Spring Boot에서는 요청을 처리할 때, 요청의 Content-Type에 따라 동작 방식이 달라진다.
- @RequestBody 는 요청 전체가 application/json 타입일 때만 사용된다.
즉, 파일과 JSON을 함께 받을 수 없다. - @RequestPart 는 요청이 multipart/form-data 타입일 때, 요청 파트별로 파일이나 JSON을 따로 처리할 수 있다.
해결
요청을 MediaType.MULTIPART_FORM_DATA_VALUE 로 설정하고, @RequestPart 를 사용
/* 예시 코드 */
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<String> upload(
@RequestPart("file", required = false) MultipartFile file,
@RequestPart("data") MyRequestDto data
) {
// 파일(선택)과 JSON 데이터(필수)를 정상적으로 받음
return ResponseEntity.ok("업로드 성공");
}
+ 추가 문제 발생
포스트맨으로 API 테스트를 할 경우, form-data 형식으로 Content-Type을 application/json 을 명시해준다면 정상적으로 동작합니다!!

하지만... Swagger에서는 "Content-Type 'application/octet-stream' is not supported"라고 예외가 발생합니다.
application/octet-stream은 MIME 타입 중 하나로, 알 수 없는 이진 파일을 의미합니다.
즉 전달하고자 하는 리소스의 유형이 명시되지 않아 인식할 수 없는 리소스인 경우에 해당 타입이 사용됩니다.
분명 swagger에서 분명히 multipart/form-data로 설정해서 보내고 있는데, 어째서 application/octet-stream 라는걸까..
확인 결과, 전체 Content-Type은 multipart/form-data이지만,
각 파트의 Content-Type은 null과 image/png였습니다.
이를 통해 파트 중 타입이 누락된 부분이 null로 들어가게 되면서 어떤 타입인지 알 수가 없어 타입이 octet-stream으로 처리되고 있었다는 것을 알 수 있었습니다.
따라서 이 문제를 해결하기 위해서는 application/octet-stream 타입을 처리할 수 있는 메시지 컨버터를 추가해야 합니다!
@Component
public class MultipartJackson2HttpMessageConverter extends AbstractJackson2HttpMessageConverter {
public MultipartJackson2HttpMessageConverter(ObjectMapper objectMapper) {
super(objectMapper, MediaType.APPLICATION_OCTET_STREAM);
}
// 해당 컨버터가 읽기 과정에서만 작동하도록 쓰기 과정은 false
@Override
public boolean canWrite(Class<?> clazz, MediaType mediaType) {
return false;
}
@Override
public boolean canWrite(Type type, Class<?> clazz, MediaType mediaType) {
return false;
}
@Override
protected boolean canWrite(MediaType mediaType) {
return false;
}
}
참고
'트러블슈팅' 카테고리의 다른 글
| Unable to load io.netty.resolver.dns.macos 오류 해결 (Mac DNS 문제) (0) | 2025.04.24 |
|---|---|
| Spring JPA Open-in-View 경고 해결 (0) | 2025.04.24 |
| Spring Data Redis: Repository store assignment 문제 해결 (0) | 2025.04.24 |