[Spring] Json with MultipartFile

반응형

이번글에서는 API 에서 Json 과 MultipartFile 을 한번에 전달받는 방법에 대해 알아보겠습니다. 

@RequestBody

먼저 API 규격상 다음의 값들을 한번에 전달받아야 한다고 가정하겠습니다. 

1. 이름
2. 나이
3. 이미지

일반적인 경우 API 에서 클라이언트에게 값을 전달받기 위해선
Request Vo 를 생성해 @RequestBody 로 데이터를 전달받도록 구현합니다. 

따라서 심플하게 생각하면..
다음과 같은 vo 를 생성해 String/Long 값과 MultipartFile 형태의 값을 한번에 전달받으면 되겠군? 이라고 생각할 수 있습니다. 

@Getter
@ToString
public class CharacterCreateRequest {
    private String name;
    private Long age;
    private MultipartFile image;
}

그렇다면, 위 vo 를 사용한 Post API 가 다음과 같을 때

@RestController
@Slf4j
public class TestController {

    @PostMapping("/api/v1/character")
    public void saveCharacter(@RequestBody CharacterCreateRequest request) {
        log.info("이름 : {}, 나이 : {}, 이미지 : {}", request.getAge(), request.getName(), request.getImage());
    }
}

API 를 정상적으로 호출할 수 있을까요?

정답은 당연히 불가능합니다..
@RequestBody 는 데이터 형식을 JSON 형태로 전달받기 때문에. 
단순히 vo 내부에 MultipartFile 형태의 필드를 추가했다고해서 해당 값을 @RequestBody 형태로 전달 받을 수 는 없습니다. 

그렇다면 어떻게 해야될까요? 🧐

@RequestPart

방법은 @RequestPart 를 사용하는 것 입니다. 

기존 vo 내부에 존재하던 MultipartFile 필드를 제거하고

@Getter
@ToString
public class CharacterCreateRequest {
    private String name;
    private Long age;
}

API 를 @RequestPart 를 사용해 다음과 같이 변경해주면 됩니다. 

@RestController
@Slf4j
public class TestController {

    @PostMapping(value = "/api/v1/character", consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.MULTIPART_FORM_DATA_VALUE})
    public void saveCharacter(@RequestPart CharacterCreateRequest request,
                              @RequestPart MultipartFile imgFile) {
        log.info("이름 : {}, 나이 : {}, 이미지 : {}", request.getAge(), request.getName(), imgFile);
    }
}

위와 같은 형태를 사용하면 하나의 API 에서Json 과 MultipartFile 을 한번에 전달받을 수 있습니다.
특이점으로는 API 에서 consumeMediaType 을 지정해줘야 한다는 점 입니다. 

만약 적절한 MediaType 을 지정하지 않을 경우
415 Unsupported MediaType ERROR 를 마주하게 됩니다. 

결론적으로 위 API 를 postman 에서 테스트해보기 위해선
다음과 같이 Body > form-data 를 선택하고 

request key 의 value 에는 json 형태의 body 값을 작성하고 
imgFile key 의 value 에는 업로드할 file 을 선택 후 API 를 호출해보면 됩니다.

이때 각 key 값의 content-type 은 application/json 과 적절한 이미지 형식 (ex image/png.. imge/jpeg) 을 선택해주면됩니다. 

실제로 API 를 호출해보면 다음과 같이 정상적으로 원하는 값들이 binding 되어 있는 것을 확인할 수 있습니다. 👏👏👏


반응형

'Spring' 카테고리의 다른 글

[Spring] Sleuth Remove Message Header  (0) 2021.09.18
[Spring] Cloud Stream Multiple Binder  (0) 2021.09.18

댓글

Designed by JB FACTORY