@RequestBody 맵핑이 안된다면?

김국민·2025년 4월 3일

Request DTO 매핑 실패 문제 해결

문제 상황

회원가입을 위해 Postman을 사용하여 POST 요청을 보냈다.

Request Body (잘못된 예시)

{
    "Name": "strd",
    "Email": "string@string.com",
    "Password": "string"
}

Controller 코드

@PostMapping("/sign-up")
public ResponseEntity<SignUpResponseDto> signUp(
        @RequestBody SignUpRequestDto requestDto
) {
    SignUpResponseDto responseDto = authService.signUp(requestDto);
    return new ResponseEntity<>(responseDto, HttpStatus.CREATED);
}

이때는 데이터베이스와 @Valid를 사용하지 않아서 요청을 받아 responseDto로 변환한 후 그대로 응답을 반환했다.
하지만 응답 값을 확인해보니 모든 필드가 null이었다.


원인 분석

SignUpRequestDto

public class SignUpRequestDto {
    private final String userName;
    private final String userEmail;
    private final String userPassword;

    public SignUpRequestDto(String userName, String userEmail, String userPassword) {
        this.userName = userName;
        this.userEmail = userEmail;
        this.userPassword = userPassword;
    }
}

문제의 원인: Postman에서 보낸 JSON의 키(Name, Email, Password)와 DTO의 필드명(userName, userEmail, userPassword)이 일치하지 않았다.

Spring MVC는 JSON을 DTO로 변환할 때 Jackson ObjectMapper를 사용하여 필드명을 자동 매핑하는데, JSON의 키와 DTO의 필드명이 다르면 자동 매핑되지 않는다.
그 결과 SignUpRequestDto의 필드 값이 null이 되었다.


해결 방법

방법 1: JSON 요청의 필드명을 DTO와 일치시키기

Postman에서 요청을 보낼 때 DTO의 필드명과 동일하게 작성해야 한다.

올바른 Request Body

{
    "userName": "strd",
    "userEmail": "string@string.com",
    "userPassword": "string"
}

이렇게 하면 Jackson이 JSON 데이터를 DTO 필드에 정상적으로 매핑할 수 있다.


방법 2: @JsonProperty 사용하여 매핑 설정하기

클라이언트가 보내는 JSON 키 값을 변경하기 어려운 경우 @JsonProperty를 활용하여 DTO 필드와 JSON 키를 매핑할 수 있다.

수정된 SignUpRequestDto

import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import org.hibernate.validator.constraints.Length;
import lombok.Getter;

@Getter
public class SignUpRequestDto {

    @NotBlank
    @Length(max = 4)
    @JsonProperty("name") // JSON의 "name"을 userName 필드에 매핑
    private final String userName;

    @Email
    @JsonProperty("email") // JSON의 "email"을 userEmail 필드에 매핑
    private final String userEmail;

    @NotBlank
    @Length(min = 5)
    @JsonProperty("password") // JSON의 "password"를 userPassword 필드에 매핑
    private final String userPassword;

    public SignUpRequestDto(@JsonProperty("name") String userName,
                            @JsonProperty("email") String userEmail,
                            @JsonProperty("password") String userPassword) {
        this.userName = userName;
        this.userEmail = userEmail;
        this.userPassword = userPassword;
    }
}

이제 Postman에서 기존대로 name, email, password를 사용해도 정상적으로 매핑된다.


결론

  • JSON 요청 필드명과 DTO 필드명을 일치시키는 것이 가장 간단한 해결책이다.
  • 클라이언트의 요청 형식을 바꾸기 어렵다면 @JsonProperty를 활용하여 매핑을 설정하면 된다.
  • Spring MVC에서 DTO 매핑이 정상적으로 이루어지려면 JSON의 키와 DTO의 필드명이 일치해야 한다.
  • Jackson ObjectMapper가 자동으로 매핑하는 방식을 이해하면 REST API 개발 시 불필요한 버그를 방지할 수 있다. 🚀
profile
개발지망생

0개의 댓글