nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of

Godtaek·2023년 11월 9일
0

Spring

목록 보기
2/9

에러 코드

Error occured org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class com.practice.sns.controller.request.UserJoinRequest]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of com.practice.sns.controller.request.UserJoinRequest (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream)

에러 원인

  1. 처음엔 생성자가 없구나! 라고 생각했다.
    1) 그런데 @AllArgs가 붙어있음
  2. Contoller의 RequestBody에 쓰일 class에서 에러가 남.
    1. @RequestBody를 이용할 경우, HttpMessageConverter를 이용해 httpBody를 매핑하게 됨.(에러코드 시작할 때 나옴)
    2. 이 때 Jackson라이브러리를 이용해 deserializer를 함. 이 때 기본 생성자가 필요함.
      에러 코드가 정직하게 모든 문제점을 알려줬다.
// UserJoinRequest.java

@Getter
@AllArgsConstructor
public class UserJoinRequest {
    private String name;
    private String password;
}
// UserController.java

@RestController
@RequestMapping("/api/v1/users")
@RequiredArgsConstructor
public class UserController {

    private final UserService userService;

    @PostMapping("/join")
    public Response<UserJoinResponse> join(@RequestBody UserJoinRequest request) {
       ...
    }
 }

해결

@Getter
@NoArgsConstructor
public class UserJoinRequest {
    private String name;
    private String password;

    @Builder
    public UserJoinRequest(String name, String password) {
        this.name = name;
        this.password = password;
    }
}

기존 @AllArgsConstructor에서 해당 코드로 변경했다.
원래 다른 생성자가 있다면 생략이 가능하며, 단일 필드 클래스인 경우에만 기본생성자가 있어야 된다는데 두 경우 해당하지 않음에도 매핑이 되지 않은 이유는 모르겠다.
다만 Jackson 라이브러리의 단일 필드 클래스 파싱의 경우 꽤 오래된 문제인듯 하다. 확장 라이브러리를 쓰면 된다는데 java17기반이라...

profile
성장하는 개발자가 되겠습니다

0개의 댓글