일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- object
- 왕실의나이트
- 나동빈
- equlas
- HashCode
- Payload
- nestJS
- makeus
- 해커톤
- 우테코
- 동등성
- 동일성
- Hackathon
- JWT
- ssh-action
- 이것이취업을위한코딩테스트다
- github action
- loop
- 딕셔너리
- remove
- 이코테
- CICD
- 너디너리
- 동빈북
- 우아한테크코스
- 라이징캠프
- forloop
- Signature
- CMC
- 컴공선배
- Today
- Total
iamjooon2님의 블로그
Lombok is- 필드 직렬화 버그 트러블슈팅 본문
요즘 진행중인 프로젝트에서는 API 응답이 성공했는지, 혹은 실패했는지를 포함한 기본 응답 포맷을 사용한다
ResponseBodyAdvice 인터페이스를 구현하여
컨트롤러의 ResponseEntity가 생성된 후, HttpMessageConverter를 거쳐 직렬화 되기 전에 공통된 응답을 감싸 보내는 형식이다
게시글 적으면서 알게 된건데, 이런걸 봉투 패턴(Envelope Pattern) 이라 하더라
아무튼 각설하고, 이 기본 응답엔 isSuccess 필드가 하나 있어서
성공하면 isSuccess : true, 실패하면 isSuccess : false를 기본으로 반환하려 한다
감싸 보내는 코드는 다음과 같다
@Getter
public class BaseResponse<T> {
private final boolean isSuccess;
private final T result;
public BaseResponse(T result) {
this.isSuccess = true;
this.result = result;
}
}
@Getter
public class ErrorResponse<T> {
private final boolean isSuccess;
private final String code;
private final String message;
private final T result;
public BaseResponse(ExceptionType exceptionType, T result) {
this.isSuccess = true;
this.code = exceptionType.getCode();
this.message = exceptionType.getMessage();
this.result = result;
}
}
별 특이한 점은 없어 보이지만, 요걸 테스트하기위해 스웨거로 API 콜 때려보면 아주 신기한 일이 발생한다
prefix인 is-가 없어져서 success가 나온다
처음엔, @JsonProperty를 사용해서 임의의 값을 설정해줬다
그랬더니 isSuccess는 생겼지만, success도 그대로 있었다
빌드 후 인텔리제이의 classes 파일을 확인했다
result 필드의 게터는 getResult()로 잘 만들어졌는데, isSuccess는 isSuccess()로 만들어졌다
근데 응답 보내면 success도 오고, isSuccess도 오잖아....
수상하다...
@JsonProperty를 지우고 다시 빌드를 돌려봤다
isSuccess()가 그대로 있다
이친구... @JsonProperty 때문에 나온 친구가 아니었다?
생각해보니 @JsonProperty는 json에 매핑해주는 놈이니, 빌드된 파일과는 상관없다..ㅋㅋㅋㅋ
결국 롬복의 @Getter 요녀석이 getIsSuccess()로 안만들고, isSuccess()로 만들었다는 얘기다
클린코드에서는 boolean 데이터 타입을 반환하는 함수의 경우, is-, can-, has-의 접두사를 붙이라고 말한다
관련이 있으려나 ?
isSuccess의 데이터 타입을 int로 바꾸고 다시 빌드를 해봤다
getIsSuccess()로 생성된다
다시 데이터타입을 boolean으로 바꿔주고, is- 접두사를 빼보고 빌드를 돌려봤다.
boolean이라 그런가 is- 가 붙어서 나온다....
결국.. 롬복이 boolean 필드의 경우 게터를 is-로 컴파일 한다는 얘기였다
그럼 롬복을 안쓰고 그냥 Getter를 만들어주면 될려나?
롬복 안쓰고 직접 get-으로 시작하는 게터들을 만들어주고 API 콜 때려봤다
잘.. 나온다....
문제는 해결했는데, 소소한 고민이 생겼다
BaseResponse는 필드가 두 개밖에 없어서 그렇다 쳐도, ExceptionResponse는 필드가 여러개인데 이거 다 게터 만들어줘야할까?
찾아보니 @Getter(AccessLevel.NONE)을 통해 특정 필드의 접근을 막을 수 있다고 한다
트러블슈팅 다 했으니.. 빠르게 글을 마무리 지어본다
해결 & 결론
롬복은 boolean 필드는 getIs-가 아닌 is- 식으로 메서드를 만든다
isSuccess는 롬복을 사용하지 않고, 직접 getter를 만들어줘서 해결했다
최종 코드는 아래와 같다
public class BaseResponse<T> {
private final boolean isSuccess;
private final T result;
public BaseResponse(T result) {
this.isSuccess = true;
this.result = result;
}
public boolean getIsSuccess() {
return isSuceess;
}
public T getResult() {
return result;
}
}
@Getter
public class ErrorResponse<T> {
@Getter(AccessLevel.NONE)
private final boolean isSuccess;
private final String code;
private final String message;
private final T result;
public BaseResponse(ExceptionType exceptionType, T result) {
this.isSuccess = false;
this.code = exceptionType.getCode();
this.message = exceptionType.getMessage();
this.result = result;
}
public boolean getIsSuccess() {
return isSuccess;
}
}
'트러블슈팅' 카테고리의 다른 글
Java optional - OrElse, OrElseGet 알고쓰자 (0) | 2023.08.20 |
---|---|
[Javascript] forEach는 async를 안기다려준다 (0) | 2022.09.07 |
[python] for loop list remove() 사용 주의점 (0) | 2022.07.17 |
[ORACLE 19C] ORA-01017: 사용자명/비밀번호가 부적합, 로그온 할 수 없습니다. (0) | 2022.04.04 |