오류 발생
application/octet-stream' is not supported 메시지를 남기는 상황
Postman으로 테스트했을 때는 문제 없었던 상황


HTTP매핑 속성도 'MULTIPART_FORM_DATA_VALUE"로 잘 했는데 왜 서버 측에서는 설정해주지도 않은 타입인 application/octet-stream으로 인식하고 있을까??
문제 원인 분석
Swagger UI의 JSON 직렬화 방식 차이
Swagger UI에서는 Multipart/form-data 요청 시 버그가 있다
- 객체(JSON) 요청일 경우 해당 데이터의 Content-Type을 제대로 지정하지 않고 전송하는 현상.
- postman은 수동으로 설정이 가능해서 문제가 없었던 것
- 서버측에서는 이를,
application/octet-stream
(기본 바이너리 타입)으로 받아들이게 된다. - 따라서
'application/octet-stream' is not supported"
가 발생

해결법 - 커스텀 컨버터 생성
조사하니까 해결하는 방법들은 여러 방법이 있다.
그 중 깔끔하고 괜찮은 방법 2개 선정(1번 방법 선호)
방법 1. 기존 컨버터 확장 or 추가 등록 🔓
Spring이 기본 적으로 등록하는 jackson기반 json 컨버터인 MappingJackson ~ 를 오버라이딩(또는 추가 등록) 할 빈을 등록하기
해당 컨버터의 지원 미디어 타입 목록에 application/octet-stream을 추가
@Configuration
public class JacksonConverterConfig {
//@Primary => 자동 vs 수동 빈 충돌 두려우면 추가
@Bean
public MappingJackson2HttpMessageConverter customJacksonConverter() {
// 1. 새로운 jackson 기반 HTTP 메시지 컨버터 생성
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
// 2. converter가 지원하는 MediaType 리스트를 복사하여 만들기
List<MediaType> supportedMediaTypes = new ArrayList<>(converter.getSupportedMediaTypes());
// 3. octet-stream도 지원하도록 추가하기
supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);
converter.setSupportedMediaTypes(supportedMediaTypes);
return converter;
// List<MediaType> supportedMediaTypes = converter.getSupportedMediaTypes();
// 이게 불변 객체 반환이라 불가능
// supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);
}
✅기존 Jackson 컨버터의 기능을 유지하면서 확장
- Spring이 기본적으로 등록하는 MappingJackson2HttpMessageConverter의 기능을 변경하지 않고 추가적인 기능만 확장
- 원래 지원하는 JSON 변환 기능은 그대로 유지하면서, 추가로 지원할 미디어 타입을 확장
✅충돌이 날 것 같지만, 수동으로 등록된 빈이 우선순위다
- 일반적으로 수동 VS 자동 등록 빈이 충돌하면 수동 등록 빈이 우선이다
- (수동 빈이 자동 빈을 오버라이딩)
- But 의도치 않은 에러가 발생할까봐 걱정이 되면 @Primary 써서 2개 등록 가능
방법 2. 커스텀 컨버터 생성 - 상속
Swagger에서 전송하는 데이터를 application/octet-stream로 변환하기 때문에, Spring이 무시하도록 설정할 필요가 있다
해결방법 개요
- application/octet-stream을 JSON으로 변환하려는 시도를 차단
- 커스텀 메시지 컨버터(MultiPartConverterConfig)를 생성하여 application/octet-stream을 무시하도록 설정
- 커스텀 컨버터가 HTTP 응답 출력을 지원하지 않도록 canWrite() 메서드를 오버라이딩하여 false 반환
@Component // 1. Abstract ~~ 상속 :
public class MultiPartConverterConfig extends AbstractJackson2HttpMessageConverter {
// 2. ObjectMapper 객체를 받아서 생성자로 받아들임
protected MultiPartConverterConfig(ObjectMapper objectMapper) {
super(objectMapper, MediaType.APPLICATION_OCTET_STREAM);
}
// 3. 모든 canWrite 메서드 다 false로 반환해서 변환 무력화
@Override
protected boolean canWrite(MediaType mediaType) {
return false;
}
@Override
public boolean canWrite(Class<?> clazz, MediaType mediaType) {
return false;
}
@Override
public boolean canWrite(Type type, Class<?> clazz, MediaType mediaType) {
return false;
}
}
✅ AbstractJackson2HttpMessageConverter를 상속받기

- Spring의 JSON 변환기인 MappingJackson2HttpMessageConverter도 AbstractJackson2HttpMessageConverter를 상속받음.
- 따라서 커스텀 클래스가 이것을 직접 상속한다면, application/octet-stream 처리 방식을 조정할 수 있다.
✅super(objectMapper, MediaType.APPLICATION_OCTET_STREAM);
- application/octet-stream 타입의 요청을 받을 때, Spring이 이 컨버터를 사용하도록 등록함.
- 이렇게 되면, octet-stream 타입을 받아들여도 예외가 발생하지 않음
- 후에, 이 타입이 받아들여지면 기본 Jackson 컨버터가 그 부분을 json으로 간주하고 파싱해주게 된다.
✅canWrite( ~~ ) 오버라이딩 : 출력차단
- 모두 false로 설정 → 이 컨버터가 HTTP 응답을 변환하는 기능을 하지 않음.
- application/octet-stream을 JSON으로 직렬화하지 않도록 차단
- octet-stream은 바이너리 데이터인데 직렬화 하는 것 자체를 막아야
- 즉, 이 컨버터가 응답 변환에는 개입하지 않도록 제한
이로 인해, Spring이 application/octet-stream타입 요청을 기본 컨버터(MappingJackson2HttpMessageConverter)에서 처리하지 않도록 함
- 처리를 커스텀 클래스에서 하고
- 나중에 파싱은 MappingJackson2HttpMessageConverter
'백엔드 > 스프링' 카테고리의 다른 글
단위 테스트가 어려운 이유: 과도한 Mocking (0) | 2025.03.29 |
---|---|
복잡한 동적 쿼리 테스트하기 (0) | 2025.03.27 |
Spring에서 파일 다운로드 코드 구현하기 (다양한 리소스) (0) | 2025.03.10 |
Swagger 오류 : Failed to load API definition (1) | 2025.02.24 |
외부 API 호출하는 방법 (feat. RestClient) (0) | 2025.02.20 |