상황
@RequestBody 를 가진 POST 요청에 대해서만 계속 400 응답이 온다
파악
ERROR 가 아닌 WARN 단계로 로그가 찍혀서 계속 못보고 지나쳤는데 잘 봐야 한다..
에러 메세지 : HttpMessageNotReadableException: JSON parse error: Cannot construct instance of ...
Spring 은 요청의 직렬화/역직렬화에 Jackson 이라는 라이브러리를 사용하고,
Jackson 은 생성자를 반드시 필요로 한다.
해결
그런데 나는 DTO 클래스에 @Data 와 @Builder 만 달고 사용중이었다.
(@Builder 는 생성자를 생성해주지 않음)
직전 프로젝트에서 잘 됐던 코드랑 비교했었는데 그때도 이렇게 잘 썼어서 문제가 없는 줄 알았다.
앞으로는 스프링 로그를 WARN이나 다른 단위까지 찍히는 게 없는지 더 꼼꼼하게 챙겨봐야 겠다.
왜 다른 프로젝트에서는 생성자없이도 잘 됐었는지가 의문이다.
DTO 클래스에 @AllArgsConstructor 와 @NoArgsConstructor 를 달아줘서 해결했다.
** @JsonProperty, @JsonAutoDetect 등 프로퍼티 기반 객체나 생성자 위임방식을 사용해도 해결 가능하다.
이것때문에 밤 샜는데, 한시간 넘게 봐도 잘 안될 때는 계속 붙들지 말고 덮자.. 나중에 환기시키고 다시 보자 특히 새벽엔 시간 가는 줄 모르니까 신경쓰기!
[더 알게 된 것]
- @AllArgsConstructor 와 @NoArgsConstructor 는 순서를 @All~ 를 @No~ 보다 위쪽에 써주어야 제대로 동작한다.
- 지양하는 롬복 어노테이션
- @AllArgsConstructor 와 @RequiredArgsConstructor 는 가급적 사용하지 않는 편이 좋다 : 롬복이 생성자를 자동 생성한 후 필드 순서를 바꾸게 되면 롬복은 생성되어있던 생성자에서 입력 파라미터 순서를 업데이트 하지 않는다. 즉 변수값들이 다른 값으로 잘못 맵핑되는 수가 있다! -> 그래서 대신 모든 파라미터를 받는 생성자를 직접 만들고, 생성자에 @Builder 를 붙이는 방법(이름으로 맵핑해서 바뀌어 들어가지 않음) 으로 대체 가능하다.
- @Data 어노테이션의 사용도 지양한다. : @Data = @RequiredArgsConstructor + @Getter + @Setter + @ToString + @EqualsAndHashCode 이고, RequiredArgsConstructor 와 EqualsAndHashCode 의 사용이 지양되기 때문이다. 대신 @Getter + @ToString (+ @Setter) 으로 사용하자.
- @Setter 이건 원래 지양했던 거 : 값이 쉽게 바뀔 수 있음
[참고]
지양하는 롬복 어노테이션 : https://velog.io/@rosa/Lombok-%EC%A7%80%EC%96%91%ED%95%B4%EC%95%BC-%ED%95%A0-annotation
'Spring boot' 카테고리의 다른 글
[실험실] ws와 http 의 세션은 개별적? (0) | 2024.09.27 |
---|---|
[RestDocs] Request parameters with the following names were not documented: [_csrf] (0) | 2023.06.20 |
<ERROR> 실행 시에 안나던 에러가 테스트 시에 발생 - @WebMvcTest 컨트롤러 지정 (0) | 2023.06.17 |
[HTTP/WS] api설계 : 소켓 통신 중 http 통신? (8) | 2023.05.24 |
<ERROR> JPA 자동 테이블 생성 create-drop 시 GenerationTarget encountered exception accepting command : Error executing DDL (0) | 2022.08.25 |