저번에 작성했던 @RequestPart를 이용한 MultipartFile, DTO 처리을 통해 postman으로 테스트 결과 정상적으로 작동하였으나 Swagger에서 테스트시 오류가 발생하여 Swagger에서도 정상 작동하도록 수정하려고 한다.
@ReqeustPart + @ReqeustPart로 DTO와 MultipartFile을 받고
cosumes을 통해 미디어 타입(또는 Content-Type)을 지정하였습니다.
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/items")
@Tag(name = "Item", description = "품목 API")
public class ItemController {
private final ItemService itemService;
@Operation(summary = "품목 추가")
@PostMapping(consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
public Response<ItemDto> createItem(@RequestPart ItemCreateRequest request, @RequestPart MultipartFile multipartFile, Authentication authentication) {
ItemDto response = itemService.saveItem(request, multipartFile);
return Response.success(response);
}
}
현재 상황에서 스웨거를 실행하면 415에러를 발생합니다.
로그를 보면 아래의 에러와 같습니다.
2023-07-25T09:48:03.820+09:00 WARN 13624 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content-Type 'application/octet-stream' is not supported]
이 클래스는 AbstractJackson2HttpMessageConverter를 상속하고, "Content-Type: multipart/form-data" 헤더를 지원하는 HTTP 요청의 처리를 위한 용도로 설계되었습니다.
MultipartJackson2HttpMessageConverter 클래스는 ObjectMapper 객체를 생성자로 받아들입니다. 이 ObjectMapper는 JSON 데이터와 Java 객체 간의 변환을 담당하는 Spring의 기본 JSON 라이브러리입니다.
또한, 해당 클래스에서는 HTTP 응답 출력을 지원하지 않도록 canWrite() 메서드들을 오버라이드하여 모두 false를 반환하도록 설정되어 있습니다. 이로 인해 이 메시지 컨버터는 주로 HTTP 요청 데이터를 객체로 변환하는 데 사용됩니다.
위 코드를 Spring 프로젝트에 추가하고 @Component 어노테이션을 통해 빈으로 등록하면 Spring 컨텍스트에서 이 클래스의 인스턴스가 생성되어 관리됩니다.
@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;
}
}
이제 Swagger에서도 아래와 같이 정상적으로 작동한다.
Reference
유익한 글이었습니다.