프론트 개발 중에 서버에 데이터를 전송했는데 에러가 발생했다.
org.springframework.web.HttpMediaTypeNotSupportedException:
Content type 'application/octet-stream' not supported
예전에도 똑같은 에러를 마주한 적이 있었는데, 대충 해결만 하고 치웠다.
application/octet-stream 이란 Content-Type은 생소해서 확실히 기억난다.
근데 이번에 또 발생했고 같은 에러였는데도 제대로 기억나지 않아서 블로그에 글을 쓰기로 마음먹었다.
이렇게 글로 남겨놓으면 기억이 오래가니까 :) 무엇보다 그냥 해결법만 보고 해결을 한 이후라 기억나지 않는 점이 큰 것 같다.
이슈 분석
const formData = new FormData();
formData.append("option", {
searchOption: searchOption
});
Api.post("/end-point", formData)
.catch(error => console.error(error));
문제가 발생한 코드이다. api 통신을 하는 코드는 axios를 래핑해서 따로 만든 모듈 문법이고 문제는 formData에 실은 option 객체가 문제였다.
예전엔 500 Server Error만 뜨길래 무작정 서버측 문제인 줄 알았지만 백엔드 분에게도 말씀드리고 나도 서버 로그를 가지고 같이 찾아봤었는데 결국은 프론트 문제였었다 ... ㅎㅎ
문제 분석
Content type ... not supported 오류는 클라이언트가 서버로 전송한 데이터의 Content-Type을 서버에서 처리할 수 없을 때 발생하는 에러다. 말 그대로 내가 보낸 데이터가 application/octet-stream 라는 Content Type인데 서버에서는 다른 타입을 받아들이고 있다는 뜻.
처음 들어본 콘텐트 타입을 내가 의도해서 보냈을 리는 없고, 결국 서버에서 받고 있는 콘텐트 타입으로 지정하지 않았다는 결론이 난다.
curl --location 'http://localhost:8080/api/end-point' \
--header 'Authorization: Bearer admin' \
--form 'json="{\"option\":\"info\"}";type=application/json'
콘텐트 타입을 확인해보기 위해 포스트맨 API 도큐먼트를 뜯어봤다.
우선 request body는 multipart/form-data 형식을 지정해뒀고, 요청 정보를 확인하기 위해서는 상태코드 200의 curl 예제를 살펴봐야 했다. 요청 예시 Example Request에는 option이라는 json 데이터를 application/json 타입으로 보내고 있었다.
결과적으로 나는 Content-Type이 application/json이 아닌 application/octet-stream 형식으로 보냈었고 서버가 이를 처리하지 못해서 발생하는 에러였다.
이슈 해결
const formData = new FormData();
formData.append("option", JSON.stringify({
searchOption: searchOption
}));
Api.post("/end-point", formData)
.catch(error => console.error(error));
JSON.stringify()를 이용해서 JSON 객체를 문자열로 변환한 후 FormData에 추가했다.
해결은 해결이고 예전에도 같은 문제를 마주했지만 왜 또 문제가 생겼나? 싶은 생각이 들었다.
그냥 단순하게 실수였다.
객체 타입이 너무 익숙한 나머지 formData에 그대로 실어버렸는데도 등잔 밑이 어둡다고 이를 찾지 못했던 것이다.... :) 단순히 application/octet-stream 이란 에러에 꽂혀서 이게 뭐지? 프론트 문제였는데... 뭐더라? 하는 생각에 사로잡히고 코드를 자세히 뜯어볼 생각을 하지 못했던 것이다.
똑같은 에러를 해결하면서 오히려 공부가 된 것 같아서 좋다.
다음 번에는 application/octet-stream과 application/json Content-Type의 차이점에 대해서 포스팅할 예정이다.