파일 첨부 시 @RequestPart

일상 회고록·2024년 1월 26일
0
post-thumbnail
post-custom-banner

안녕하세요!

이번 포스트는 간단한 회고입니다.

예전 개발을 막 시작할 응애응애 개발자일 코생아 당시 파일(이미지 포함)을 REST API로 주고 받는 기능을 구현해야 할 때가 있었습니다.

아무것도 몰라서 무지성 DTO, 무지성 @RequestBody를 남발할 때 였죠.

당시 경험을 그대로 가져왔습니다.

첨부파일을 어떻게 보내야 할지 모르겠다구요? @RequestBody 밖에 모르신다구요?

환영합니다.

1. @RequestBody 이슈

때는 바야흐로 열심히 첨부파일 관련 API를 구현하던 중 문득 API 끼리 첨부파일을 주고 받을 때는 어떻게 해야하지?

라는 순수한 궁금증이 생겼습니다.

항상 JSON 형식의 데이터만 주고 받았기 때문에, @ResponseBody 를 통해 JSON 데이터를 자바 객체로 변환하여 사용해 왔습니다.

누구나 느끼겠지만, 이미지를 포함한 파일을 JSON 형식으로 주고 받는 것은 뭔가 부자연스럽다고 생각했습니다.

검색해본 결과 미디어 파일의 경우 multipart/form-data 형식으로 받아서, 다른 변환이 필요했습니다!

바로 @ResponseBody가 아닌 @RequestPart를 사용해야 했는데요.

사용법을 알아보겠습니다.

2. @RequestPart

@RequestPart는 HTTP request body에 multipart/form-data 가 포함되어 있는 경우에 사용하는 어노테이션입니다.

제 상황과 같이 MultipartFile이 포함되어 있는 경우 해당 어노테이션을 사용하게되면

MultipartResolver가 동작하여 역직렬화를 하게 됩니다.

만약 MultipartFile이 포함되어있지 않다면, @RequestBody와 마찬가지로 동작하게 됩니다.

함께 사용하는 옵션으론 여러가지가 있습니다.

  • value : ‘file’로 설정한 경우, Multipart 요청에서 "file"이라는 이름을 가진 파트를 추출하겠다는 의미입니다.
  • required : false인 경우는 MultipartFile이 필수가 아니며, 없어도 됩니다. 만약 required = true 로 설정한 후 미디어 파일을 요청하지 않는다면 예외가 발생합니다.

2-1. 시행착오

끄덕끄덕 이해한뒤 바로 적용해 보았습니다

//controller
@PostMapping("/user")
public void getUser(@RequestBody UserRequestDto dto, @RequestPart(value="file", required=false) MultipartFile file){
	//
	...
}

처음엔 위와 같은 방법으로 기존의 받던 JSON 데이터의 경우는 그대로 @ResponseBody 를 사용하고,

미디어 파일의 경우만 @RequestPart 를 적용해주었습니다.

내 자신을 칭찬하며 실행해본 결과,, 에러가 떴는데요

POST한 데이터가 잘 도착하지 않고 계속 알 수 없는 예외만 보여주고 있는 상황이었습니다.

무엇이 문제였을까요?

2-2. 문제해결

알고보니 기존의 JSON 데이터를 @RequestBody이 아닌 마찬가지로 @RequestPart를 적용해주어야 했습니다.

다만 주의할 점은 JSON 데이터의 경우 MediaType을 반드시 application/json 으로 지정해주어야 합니다.

위의 코드를 정정해본다면 아래와 같습니다.

//controller
@PostMapping("/user")
public void getUser(@RequestPart(value="request") UserRequestDto dto, @RequestPart(value="file", required=false) MultipartFile file){
	//
	...
}

원할한 예시를 위해 포스트맨 요청 예시도 보겠습니다.

기존 JSON 데이터를 form-data의 텍스트 형식으로 작성한 후 MediaType을 application/json 으로 지정해준 걸 볼 수 있습니다.

실행 결과 요청이 정상적으로 잘 전달 되었습니다.


읽어주셔서 감사합니다!!


References

[Spring] @RequestPart를 사용해보자

profile
하고 싶은 것들이 많은 개발자입니다
post-custom-banner

0개의 댓글