참고
밸덩 sprint-boot-multipart-requests
api로 json 데이터 or path variable, parameter 만 다루다가 한번쯤 마주치게 되는 파일 데이터 받아서 쓰기... 항상 헷갈리는 부분이라 정리해두려고 한다!
spring에서 기본적으로 제공해주는 MultiPartFile을 사용하여 file 데이터를 전송 받으면 된다. 파일은 웹에서는 고정적으로 Form-Data로 넘어오기 때문에 이 부분 설정만 잘 맞춰주면 받기 어렵지 않다!
@RestController
@RequestMapping("/v1/member")
public class MemberController {
@PostMapping(consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
public ResponseEntity<CommonResponse<?>> modifyMember(MultiPartFile file1){
return null;
}
}
만약 파일만 받기를 원한다면 다음과 같이 작성하면 파일 1개를 받아올 수 있다.
첫번째 방법은 요청하는 쪽에서 모두 form-data로 담아서 보낼 경우다. 해당 경우가 제일 간단하게 해결이 가능하다.
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class TestDto {
private String name; // 닉네임
private String job; // 직업
private String address; // 주소
private MultipartFile image0; // 메인이미지
private MultipartFile image1; // 이미지1
private MultipartFile image2; // 이미지2
private MultipartFile image3; // 이미지3
private MultipartFile image4; // 이미지4
private MultipartFile image5; // 이미지5
...
}
다음과 같이 넘어오는 데이터가 file과 회원 데이터가 포함되어 넘어올 경우에는 다음과 같이 Dto를 작성해준다.
@RestController
@RequestMapping("/v1/member")
public class MemberController {
@PostMapping(consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
public ResponseEntity<CommonResponse<?>> modifyMember(TestDto testDto){
return null;
}
}
그리고 Controller에서는 consumes
에만 Media Type을 정의해주면 Dto 앞에 생략된 @ModelAttribute
에서 자동으로 Dto에 형태에 알맞게 데이터를 넣어준다.
데이터를 전송해보면 잘 받아오는 것을 확인할 수 있다.
두번째 방법은 @RequestPart
를 사용하는 방법이다. 해당 어노테이션은 요청 정보를 부분별로 받아볼 수 있게 만들어주는데 위 방식처럼 form-data에 모두 담아 보내는게 아니라 json+file 데이터 형식으로 받아볼 때 사용하면 좋을 것 같다.
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class TestDto {
private String name; // 닉네임
private String job; // 직업
private String address; // 주소
}
위의 dto를 다음과 같이 변경한다. MultiPartFile 부분을 모두 제거하면 된다.
@PostMapping(value = "/test",consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.MULTIPART_FORM_DATA_VALUE})
public ResponseEntity<CommonResponse<?>> modifyMemberTest(@RequestPart TestDto dto, @RequestPart List<MultipartFile> files){
return null;
}
그 후에 @RequestPart
를 사용하여 각각의 MediaType을 정의해준다.
다음과 같이 요청을 하게 되면 우리가 생각한 데이터로 받아볼 수 있게 된다. 만약 file을 하나씩 받고 싶다면 List<MultiPartFile>
대신 하나씩 지정해서 넣어주면 된다.
MultiPartFile file1, MultiPartFile file2
이런 방식으로 사용하면 된다.