Swagger 설정 중 401 오류 및 multipart/form-data JSON 전달 문제 해결

송현진·2025년 4월 5일
0

Spring Boot

목록 보기
7/23

1. Swagger 설정 후 401 에러 발생

Swagger UI 적용을 위해 다음 의존성을 추가했다.

implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0'

그런데 /swagger-ui/index.html 접속 시 401 Unauthorized 에러가 발생했고, 콘솔에는 NoSuchMethodErrorControllerAdviceBean 관련 오류 발생했다.

🔍 원인

springdoc-openapi 2.5.0 버전이 내가 사용 중이던 Spring Boot 3.4.4 버전과 호환되지 않는 것이었다.

springdoc 내부에서 사용하는 API가 Spring 3.2.x 기준이었다...

🛠️ 해결

Spring Boot 버전을 3.2.5로 다운그레이드했더니 Swagger UI에 접속을 성공했다.

2. multipart/form-data로 JSON + 이미지 전송 시 application/octet-stream 에러 발생

상품 등록 API에서 이미지와 상품 데이터를 동시에 @RequestPart로 받도록 설계했다.

@Operation(summary = "상품 등록", description = "상품 정보를 등록합니다. 이미지 파일은 Multipart 형식으로 첨부합니다.")
@PostMapping(consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
public ResponseEntity<?> createItem(
    @Parameter(description = "상품 데이터(JSON)") @RequestPart("data") ItemRequestDto requestDto,
    @Parameter(description = "상품 이미지 파일들") @RequestPart(value = "images") List<MultipartFile> images,
    @AuthenticationPrincipal UserDetailsImpl userDetails) throws IOException {
    ...
}

Swagger에서 요청 시 JSON을 application/json이 아닌 application/octet-stream 으로 보내버려서 아래 에러 발생했다.

Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: 
Content-Type 'application/octet-stream' is not supported]

🔍 원인

Swagger의 @RequestPart 지원이 제한적이라 JSON을 직렬화하지 못하고 이진 데이터로 보내버린다. 쉽게 말하면 JSON 데이터를 보내려고 해도, 내부적으로 그걸 일반 JSON이 아니라 ‘파일처럼’ 이진 데이터 (octet-stream) 으로 보내버리기 때문이다.

🛠️ 해결

application/octet-stream 처리를 Jackson이 하지 않도록 커스텀 컨버터 등록했다.

@Component
public class MultipartJackson2HttpMessageConverter extends AbstractJackson2HttpMessageConverter {
	
    // Swagger가 보내는 'application/octet-stream' 요청을 무시하게 설정
    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;
    }
}

이 컨버터는 application/octet-stream 타입을 아예 무시하게 하므로, Jackson이 application/json 처리 쪽으로 넘어가게 된다.

"이진 데이터는 무시하라"는 설정을 해주는 커스텀 HttpMessageConverter`를 만들어서,
Spring이 "이건 처리 안 해도 되는 거구나" 하고 넘기게 한 것이다.

Swagger에서도 JSON과 이미지를 동시 전송 성공하게 되었다.

📝 배운 점

  • 라이브러리 버전 호환성이 얼마나 중요한지 다시금 체감
  • Swagger 사용 시 @RequestPart를 쓸 때는 JSON 직렬화 처리 방식을 정확히 이해하고 있어야 함
  • 에러 메시지에서 MediaTypeNotSupported가 나왔다면 컨버터 체인을 의심해볼 것
  • 직접 HttpMessageConverter를 구현하거나 확장해 적용하는 방법을 익힘
profile
개발자가 되고 싶은 취준생

0개의 댓글