spring multipart file 받아오기

최준호·2022년 11월 9일
4

업무

목록 보기
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
해당 주소로 이전하였습니다. 감사합니다. https://ililil9482.tistory.com

0개의 댓글