에러를 처리하는 곳에서 에러가 났다...😱
(이것은.. 무한 에러 루프..?)
Spring Boot에서 공통 익셉션을 처리하기 위해 @RestControllerAdvice, @ExceptionHandler를 사용하여 개발하고 있었다. 익셉션처리가 잘 되는지 확인하기 위해 service단에서 익셉션을 날렸다. 근데 읭? 원하는 에러가 나기 전에 아래와 같은 에러를 뱉었다. 분명 다른 분들의 글을 총집합하여 예제를 잘 따라한 것 같은데.. 🤷🏻♀️ 해결해보자...!
에러 내용
ExceptionHandlerExceptionResolver : Failure in @ExceptionHandler com.itevent.iteventapi.common.error.ControllerExceptionHandler#handleIllegalArgumentException
org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
- 주 키워드 : ExceptionHandlerExceptionResolver, HttpMediaTypeNotAcceptableException
해결 과정
해결하기 위해 시도해본 것은 다음과 같다.
- 에러 내용에 대해 검색 -> 보류
- 에러 내용 찾아봤는데 다들
MappingJackson2HttpMessageConverter
문제라고 한다..
사실 잘 안써봐서 모르기도 하고 Controller에서는 정상으로 Json 잘 리턴했었는데 갑자기 Jackson이 제대로 등록 안되어있다는 게 이상했다. 모르는데 막 했다가 코드 꼬일거같아서 시도하지 않았다.(메시지 컨버터는 공부해야겠다.. 으휴 모르는게 한바가지)
- 에러 내용 찾아봤는데 다들
- timestamp 필드 제거해보기 -> 같은 에러 발생
- HashMap으로 리턴해보기 -> 잘된다. 즉 에러처리 후 ResponseEntity를 리턴할 때 무언가 문제라는 소리다.
- 컨트롤러에서 사용중이던 정상버전용 Response 객체를 리턴해보기-> 된다?!
- Controller에서 정상일 때 JsonResponse객체를 담은 ResponseEntity를 반환해보았다.(event는 대충 기본생성자로 대체함)
-> 그랬더니 에러 안나고 잘 돌아간다..?!! return new ResponseEntity<JsonResponse>(new JsonResponse(event), HttpStatus.OK);
- Controller에서 정상일 때 JsonResponse객체를 담은 ResponseEntity를 반환해보았다.(event는 대충 기본생성자로 대체함)
- (그렇다면 정말 마지막으로..) 돌아가는 JsonResponse객체와 ErrorResponse 객체 비교해보기
- 대체 같은 반환객체를 만든건데 뭐가 다른가 했더니 상단 어노테이션이 의심된다.
- JsonResponse의 어노테이션 : @Setter, @Getter
ErrorResponse의 어노테이션 : @Builder - 각 어노테이션을 붙여다 뗏다 물리적(?) 테스트를 완료한 결과, @Getter만 있으면 정상으로 해결되었다.
- JsonResponse의 어노테이션 : @Setter, @Getter
- 대체 같은 반환객체를 만든건데 뭐가 다른가 했더니 상단 어노테이션이 의심된다.
해결 방법
- 제작한 Response객체에 @Getter (혹은 Getter 메서드)를 붙여주어야 한다.
원인 분석
그렇다면 대체 왜 Getter 메서드가 필요하지? Builder든, 생성자든 셋팅할 수 있는 생성용 메서드만 필요한게 아니고? 누가 이 문제에 대한 힌트를 줬으면 좋게따..😂
(분석 내용 추가 21.03.18)
- Getter가 필요한 이유 !?
현재 내 프로젝트에서는 Jackson 라이브러리를 통해서 객체 형태를 Json구조로 반환하고 있다. Jackson은 내부적으로ObjectMapping API를 사용하여 객체를 json으로 변환한다. Jackson 라이브러리는 Getter/Setter 프로퍼티를 기준으로 작동한다. 별다른 옵션을 주지않는 한 Getter/Setter를 사용하여 변환작업을 수행한다. 그래서 내가 Getter를 넣지 않았을 때 내부적으로 Getter의 역할을 할 프로퍼티를 찾지 못해 에러가 난것으로 추측된다.
(+ 꼭 Getter/Setter를 쓰지 않고 @JsonProperty
, @JsonAutoDetect
를 사용해 멤버변수를 프로퍼티로 지정할 수도 있다.)
내용 참고
'Spring' 카테고리의 다른 글
[Spring] Bean property '필드명' is not readable or has an invalid getter method 에러 해결 (2) | 2021.03.29 |
---|---|
[Spring] ModelMapper Entity to DTO 변환 시 프로퍼티 null 해결 (0) | 2021.03.24 |
[SpringBoot] h2-console 웹 접근안될 때 해결 방법 (0) | 2021.03.08 |
[Spring/JPA] @DynamicUpdate, Validation 동시 적용 시 Validation 에러 해결 (0) | 2020.10.11 |
[Lombok] @Builder 사용 시 @NoArgsConstructor 관련 에러 해결 (7) | 2020.09.07 |