일기 어플에서 일기를 쓸 때 사진과 음성 파일도 업로드 할 수 있게 변경하는 도중 문제가 생겼다. 한 엔드포인트단에서 전부 처리해줘야하는데 JSON과 파일을 같이 받으면 둘 다 인식이 안 되는 문제. 2일동안 찾아내다가 결과를 찾았다
테스트를 위한 컨트롤러 수정
@PostMapping(value = "create", consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.MULTIPART_FORM_DATA_VALUE})
@Operation(summary="일기 등록")
public ResponseEntity<Diary> addDiary
(@RequestPart AddDiaryRequest request, @RequestPart MultipartFile file, Principal principal) {
if(file!=null)
{
System.out.println(file.getOriginalFilename());
}
Diary savedDiary = diaryService.save(request, principal.getName());
return ResponseEntity.status(HttpStatus.CREATED)
.body(savedDiary);
}
DTO의 경우 기존에 @RequestBody로 받았는데 이렇게 받으면 추가로 다른 데이터를 받을 수가 없다. 그리고 DTO 안에 MultiPartFile 변수를 추가해서 처리하는 경우 데이터 전송 시 절차가 복잡해지게 된다. 이럴때 @RequestPart를 사용하면 Body 부분을 나눠서 전송할 수 있어서 문제가 해결된다. JSON 형식과 FORM 형식을 둘 다 받아야 하므로 consumes에 형식 두개를 다 넣어주고 코드처럼 받아주면 JSON과 파일 모두 받을 수 있게 된다.
하지만 더 헤맨게 Swagger에서 테스트가 불가능하다는것이었는데, Swagger는 RequestPart 두개의 형식을 하나로 통일해서만 보낼 수 있었기 때문. 그래서 개발 초창기에 사용하던 Postman을 다시 사용했다.
헤더에 Bearer token값을 일일히 넣어줘야하는건가 했지만 Authorization 탭이 있어 그냥 설정만 해주면 인증도 된다.
그 후 Content-Type을 정확히 명시해주고 JSON 데이터는 JSON 형식으로, Mulipart 데이터는 파일 업로드를 하여 테스트 끝.
@ModelAttribute를 이용하는 방법도 있지만 테스트할 시 이렇게 RequestPart로 나눠서 하는것이 더 간단하고 편한 방식이기에 이 방법을 선택하였다.
이제 파일을 저장하고 불러오는 서비스 코드만 작성하면 완료된다. 이미지 파일의 경우 다중 업로드를 지원해야하기에 List<MultiPartFile>로 받으면 완료.