2023. 10. 5. 10:57ㆍ에러 창고
[Reason]
간단히 만든 회원가입 api는 json 형식의 Dto 객체 데이터와 이미지를 받는 multipart 형식의 데이터를 요청 변수로 받고 있다.
그리고 Swagger 를 적용하고 실행하여 각각 알맞게 데이터를 넣어주고 try it out 을 실행했을 때 위와 같이 415 : Content-Type 'application/octet-stream' is not supported 에러가 발생하였다.
위의 api에서도 볼 수 있듯이 consumes 속성도 추가해주었고, produces 속성도 추가하여 알맞은 데이터 형식으로 매핑해주었고, 혹시나 해서 각각 파라미터마다 @Parameter 어노테이션을 붙여 content 속성까지 추가하여 한번 더 알맞은 형식의 데이터임을 swagger에게 알려주도록 하였다.
또한, properties 파일에 따로 넣어준 springdoc.default-consumes-media-type, springdoc.default-produces-media-type 설정값도 정확한 데이터 형식을 명시해주었는데도 불구하고 이와 같은 에러가 지속적으로 발생하였다.
[Solution]
에러 메세지에서도 알 수 있듯이 application/octet-stream 이라는 데이터 형식을 지원하지 않는다고 나와있는데, 이는 json Dto 객체 요청 변수가 아닌 이미지 파일을 요청 받는 multipart 요청 데이터 쪽에서 문제가 발생한 것이였다.
이를 해결하기 위해서는 multipart/form-data를 지원받을 수 있도록 application/octet-stream 으로 인식하게끔 convert 해주는 작업이 필요하다.
MultipartJackson2HttpMessageConverter
package music.is.my.life.musicismylife.share;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter;
import org.springframework.stereotype.Component;
import java.lang.reflect.Type;
@Component
public class MultipartJackson2HttpMessageConverter extends AbstractJackson2HttpMessageConverter {
/**
* "Content-Type: multipart/form-data" 헤더를 지원하는 HTTP 요청 변환기
*/
public MultipartJackson2HttpMessageConverter(ObjectMapper objectMapper) {
super(objectMapper, MediaType.APPLICATION_OCTET_STREAM);
}
@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;
}
}
그러므로 convert 해주는 클래스를 만들어준다.
이 클래스는 AbstractJackson2HttpMessageConverter를 상속하고, "Content-Type: multipart/form-data" 헤더를 지원하는 HTTP 요청의 처리를 위한 용도로 설계되었다.
MultipartJackson2HttpMessageConverter 클래스는 ObjectMapper 객체를 생성자로 받아들입니다. 이 ObjectMapper는 json 데이터와 Java 객체 간의 변환을 담당하는 Spring의 기본 JSON 라이브러리이다.
또한, 해당 클래스에서는 HTTP 응답 출력을 지원하지 않도록 canWrite() 메서드들을 오버라이드하여 모두 false를 반환하도록 설정되어 있다.
이로 인해 이 메시지 컨버터는 주로 HTTP 요청 데이터를 객체로 변환하는 데 사용된다.
해당 컨버터 클래스만 만들고 다시 swagger 를 실행하면 정상적으로 요청되고 응답받는 것을 확인할 수 있다.