회원가입을 위해 Postman을 사용하여 POST 요청을 보냈다.
{
"Name": "strd",
"Email": "string@string.com",
"Password": "string"
}
@PostMapping("/sign-up")
public ResponseEntity<SignUpResponseDto> signUp(
@RequestBody SignUpRequestDto requestDto
) {
SignUpResponseDto responseDto = authService.signUp(requestDto);
return new ResponseEntity<>(responseDto, HttpStatus.CREATED);
}
이때는 데이터베이스와 @Valid를 사용하지 않아서 요청을 받아 responseDto로 변환한 후 그대로 응답을 반환했다.
하지만 응답 값을 확인해보니 모든 필드가 null이었다.
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이 되었다.
Postman에서 요청을 보낼 때 DTO의 필드명과 동일하게 작성해야 한다.
{
"userName": "strd",
"userEmail": "string@string.com",
"userPassword": "string"
}
이렇게 하면 Jackson이 JSON 데이터를 DTO 필드에 정상적으로 매핑할 수 있다.
클라이언트가 보내는 JSON 키 값을 변경하기 어려운 경우 @JsonProperty를 활용하여 DTO 필드와 JSON 키를 매핑할 수 있다.
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를 사용해도 정상적으로 매핑된다.
@JsonProperty를 활용하여 매핑을 설정하면 된다.