반응형
에러 발생
개발하면서 다음과 같은 에러가 발생했다.
JSON parse error: Cannot construct instance of org.example.springai.dto.AiChatRequest (although at least one Creator exists):
cannot deserialize from Object value (no delegate- or property-based Creator)]
아래와 같이 생성자가 하나일 때 발생한 에러.
data class AiChatRequest(
val userInput: String
)
Jackson이 객체를 역직렬화할 때는 두 가지 전략을 사용하여 데이터를 객체로 변환한다.
- Delegating-based: 하나의 값(예: 문자열, 숫자 등)만을 필드로 갖는 경우 그 값을 해당 클래스에 직접 전달하여 생성자를 호출한다. 이를 통해 단일 값으로 생성할 수 있는 객체에 적합하다.
- Properties-based: 클래스 내의 여러 필드를 이용해 객체를 생성하는 방식이다. 이 방식은 JSON에서 키-값 쌍을 각각 클래스의 필드에 매핑합니다. 즉, JSON의 각 속성을 클래스의 필드에 직접 대응시킨다.
Jackson은 필드가 1개일 때 어느 방식으로 역직렬화할지 알지 못해 오류를 발생시키는 경우가 있다. AiChatRequest 클래스가 필드가 1개인 경우, Jackson은 이를 단일 값으로 취급해야 하는지, 아니면 키-값 쌍으로 취급해야 하는지 결정할 수 없어서 발생하는 문제다.
해결법
기본 값 제공 방법 (이 방법으로 해결)
Kotlin에서 제공하는 기본값은 Jackson이 기본 생성자를 호출할 수 있게 하며, 이로 인해 Jackson이 역직렬화를 올바르게 수행할 수 있게 된다. 필드가 없을 경우에는 기본값을 사용하고, 값이 제공될 경우 해당 값을 사용하게 된다.
data class AiChatRequest(
@NotBlank(message = "User input must not be blank")
val userInput: String = ""
)
그 외 방법 - @JsonCreator 사용
단일 필드 클래스에서 Jackson에게 명시적으로 생성자를 사용하도록 지시할 수 있습니다. 이를 위해 @JsonCreator와 @JsonProperty 어노테이션을 사용하여 Jackson이 올바르게 역직렬화할 수 있게 도울 수 있습니다.
data class AiChatRequest(
@JsonProperty("userInput")
@NotBlank(message = "User input must not be blank")
val userInput: String
)
하지만 `@JsonProperty` 어노테이션을 사용하는 것은 다른 개발자가 그 이유를 쉽게 유추하기 힘들기 때문에, 사용하지 않는 것이 더 낫다고 판단했다.
REFERENCES
[Spring] Kotlin에서 data class의 필드가 1개일 때 역직렬화가 안 되는 문제 (no delegate- or property-based Creator) - https://cl8d.tistory.com/111
반응형