spring multipart file 받아오기

최준호·2022년 11월 9일
3

업무

목록 보기
25/31
post-thumbnail

참고 밸덩 sprint-boot-multipart-requests

😂 파일 전송이 제일 헷갈려!

api로 json 데이터 or path variable, parameter 만 다루다가 한번쯤 마주치게 되는 파일 데이터 받아서 쓰기... 항상 헷갈리는 부분이라 정리해두려고 한다!

📄 file은 MultipartFile!

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개를 받아올 수 있다.

👏 해결 방법

✅ @ModelAttribute (parameter + file)

첫번째 방법은 요청하는 쪽에서 모두 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 (json + file)

두번째 방법은 @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 이런 방식으로 사용하면 된다.

profile
코딩을 깔끔하게 하고 싶어하는 초보 개발자 (편하게 글을 쓰기위해 반말체를 사용하고 있습니다! 양해 부탁드려요!) 현재 KakaoVX 근무중입니다!

0개의 댓글