본문 바로가기

프로그래밍/Spring

[Spring] DTO, MultiPartFile 동시에 요청하기

User의 프로필을 수정하는 기능을 만들기 위해 UserUpdateDto 를 만들었다.

 

업데이트 내용에는 이름, 소개 글, 프로필 이미지가 포함 되는데

 

아래와 같이 RequestBody로 String인 username, profileText, MultipartFile인 image를 JSON타입으로 같이 받을 수 없었다.

class UserUpdateDto{
    private String username;
    private String profileText;
    private MultipartFile image;
}

그래서 DTO에서 MultipartFile을 제외 시키고

class UserUpdateDto{
    private String username;
    private String profileText;
}

RequestPartUserUpdateDtoImage를 한번에 따로 받는 방식을 택했다.

    @PutMapping("/api/v1/user/{id}")
    public Long updateUser(Model model, 
                    @PathVariable Long id, 
                    @RequestPart(value = "updateUserRequestDto") UpdateUserRequestDto updateUserRequestDto, 
                    @RequestPart(value = "imageFile", required = false) MultipartFile imageFile) {

    }

JavaScript 에서는 formData를 만들고

 

컨트롤러에서 value 로 설정해준 key 값으로 ("updateUserRequestDto", "imageFile")

 

JSON으로 만든 DTOImage 파일을 formData에 Append 시켜서 보낸다.

function updateUser(){
    const formData = new FormData(profileForm); 

    const profileForm = document.getElementById("user-profile-form");

    const updateUserRequestDto = {
        username: formData.get('username'),
        profileText: formData.get('profileText')
    };
    
    // formData에 DTO를 JSON으로 Append
    formData.append('updateUserRequestDto', new Blob([JSON.stringify(updateUserRequestDto)] , {type: "application/json"}));

    const imageFileInput = document.getElementById('user-profile-img');
    
    // formData에 Image Append
    formData.append('imageFile', imageFileInput.files[0]);

    $.ajax({
        type: 'PUT',
        url: '/api/v1/user/' + id,
        data: formData,
        processData: false,
        contentType: false
    }).done(function(){
        window.location.href = '/';
    }).fail(function (error){
        alert(JSON.stringify(error));
    });
}