타 API 와 통신해서 AWS S3 에 업로드 할 일이 생겼다.
MSA 에 맞춰서 다른 팀에서 S3 에 업로드하는 API 를 뚫어줬는데,
업로드 할 binary file 데이터 타입을 MultipartFile 로 만들어주셨다..
그렇기에 내가 할 일이란
타 API 와 통신 -> byte array 겟! -> File 객체로 변환 -> MultipartFile 객체로 변환하는 것이었다.
여기서 중요했던건 ★ no disc , in memory(buff) ★ 에 초점을 맞췄다는 점이다.
왜냐면 통신해서 받은 데이터를 S3 에 업로드할건데 굳이 was 에 올릴 필요가 없었기 때문에 !!( 사실은 일정 환경 이상에서 디렉토리 핸들링 권한이 없어서 was 에 저장 자체가 불가능했음.. )
(byte[] -> MultipartFile 로 바로 변환하고 싶었지만 도저히 각도 안나오고 방법이 없어서 중간단계로 File 을 거쳤다)
// !-- 메모리에 저장하기 위해서는 OutputStream 말고 ByteArrayOutputStream 을 써야한다. --!
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(totalCnt)) {
// byte[] data size each
for () {
// byte[] read
...
// byte 하나하나 읽으면서 ByteArrayOutpurStream 에 저장
while() {
...
byteArrayOutputStream.write(byteArray);
byteArrayOutputStream.flush();
}
}
// 읽은 파일은 S3 업로드하기 위해 MultipartFile 객체로 변환한다
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
MultipartFile multipartFile = new MockMultipartFile("fileName", byteArrayInputStream.readAllBytes());
// !-- MockMultipartFile 은 원래 테스트용으로 만들어졌으나 MultipartFile 객체를 생성하기 위해 사용하기도 한다. --!
}
위 코드에서 중요한 객체
1. ByteArrayOutputStream
2. ByteArrayInputStream
3. new MockMultipartFile() -> 참고
하지만 이 글을 작성하기로 마음먹은건 그 이후다..
내가 생성한 MultipartFile 을 API 통신하려고 보냈더니 얘가 자꾸 500 에러가 났었다.
No serializer found for class java.io.ByteArrayInputStream and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ); nested exception is com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class java.io.ByteArrayInputStream and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: org.springframework.web.multipart.commons.CommonsMultipartFile["fileItem"]->org.apache.commons.fileupload.disk.DiskFileItem["inputStream"])
-> 이거는 통신할 때 exchage 메소드에서 HttpHeaders 에 ContentType 을 "multipart/form-data" 로 세팅해주는 걸로 찾아서 찔러야 한다. (회사 내부 프레임워크 살펴볼 것)
혹시 그 이후에도 500에러가 났다? 그 에러가 MissingServletRequestPartException 즉, 저 multipartFile 을 분명 던졌는데 다른 서버에서 못받는다? 그러면 던질때 포멧을 다시 확인해보자..
// file 을 이렇게만 던졌다면
new ByteArrayResource(file.getBytes())
// fileName 을 오버라이딩해서 이렇게 던져보자. 이렇게 해야지 상대 서버에서 받아주는 것 같다.
new ByteArrayResource(file.getBytes()) {
@Override
public String getFilename() throws IllegalStateException {
return URLEncoder.encode(file.getName(), StandardCharsets.UTF_8);
}
}
'Backend > JAVA' 카테고리의 다른 글
[JAVA] SHA256 암호화 Util (0) | 2021.01.13 |
---|---|
[JAVA] CURL 로 다른 API 호출하는 방법 (with. HttpClient) (0) | 2020.12.01 |
[JAVA] List 반복문 안에서 객체 remove (feat.ConcurrentModificationException) (0) | 2020.08.06 |
[JAVA] 객체(Model) 를 통으로 화면에 찍기 (대체:@Data, .toString()) (0) | 2020.05.11 |
[Java] 문자열이 Enum 에 포함되어 있는지 확인하는 방법 (0) | 2020.03.23 |
댓글