요건
- 화면에서 전달 받은 압축파일을 해제
- 해제한 파일 중 하나를 다른 서버의 API로 전송
- 상대 시스템은 Python 3.8, FastAPI로 구성됨
- Parameter는 Binary 파일, String으로 구성
- Content-Type은 multipart/form-data
테스트 코드
MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
params.add("파라미터1", new ByteArrayResource(파일 내용 byte[]));
params.add("파라미터2", "문자열 값");
HttpHeaders uploadheaders = new HttpHeaders();
uploadheaders.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<?> uploadEntity = new HttpEntity<>(params, uploadheaders);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<SttCommonResultResponseDto> responseEntity = restTemplate.exchange(
requestUrl,
HttpMethod.POST,
uploadEntity,
SttCommonResultResponseDto.class
);
1차 실행 결과
- 디버그 로그(해당 코드에서는 파라미터2는 전송하지 않음, 비필수 값)
15:51:45.985 [main] DEBUG org.springframework.web.client.RestTemplate - Accept=[application/json, application/*+json]
15:51:45.998 [main] DEBUG org.springframework.web.client.RestTemplate - Writing [{파라미터1=[Byte array resource [resource loaded from byte array]]}] as "multipart/form-data"
15:52:50.949 [main] DEBUG org.springframework.web.client.RestTemplate - Response 422 UNPROCESSABLE_ENTITY
{
"detail": [{
"loc": ["body", "파라미터1"],
"msg": "Expected UploadFile, received: [class 'str']",
"type": "value_error"
}
]
}
원인 분석(불확실함)
- multipart 업로드는 로컬 파일을 업로드 하는데 사용하는 방식
- new ByteArrayResource()를 RestTemplate의 파라미터로 설정 시 파일에 대한 정보가 없어 메모리 상의 데이터를 전송함
- 파일 메타데이터 없이 byte 배열만 전송하여 FastAPI에서 String으로 인식하게 되는 것이 원인인 것으로 판단됨
변경 코드
Path path = Paths.get("Uuid 임시 파일 위치");
MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
params.add("파라미터1", new PathResource(path));
params.add("파라미터2", "문자열 값");
HttpHeaders uploadheaders = new HttpHeaders();
uploadheaders.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<?> uploadEntity = new HttpEntity<>(params, uploadheaders);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<SttCommonResultResponseDto> responseEntity = restTemplate.exchange(
requestUrl,
HttpMethod.POST,
uploadEntity,
SttCommonResultResponseDto.class
);
2차 실행 결과
- 디버그 로그(해당 코드에서는 파라미터2는 전송하지 않음, 비필수 값)
16:25:10.079 [main] DEBUG org.springframework.web.client.RestTemplate - Accept=[application/json, application/*+json]
16:25:10.087 [main] DEBUG org.springframework.web.client.RestTemplate - Writing [{파라미터1=[path [Uuid 임시 파일 위치]]}] as "multipart/form-data"
16:25:38.558 [main] DEBUG org.springframework.web.client.RestTemplate - Response 200 OK
정리
- Python FastAPI와 통신할 때 multipart/form-data 전송 시 byte 배열을 전송하면 타입 오류가 발생할 수 있음
- In-Memory 데이터로 전송하지 않고 임시 파일을 생성해 전송하는 방식을 사용하면 타입 오류를 방지할 수 있음
- 임시 파일 생성 방식을 사용할 때 Disk Full 이슈를 방지하기 위해 주기적 삭제 혹은 작업 완료 후 삭제 같은 정책이 있어야 함