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' 카테고리의 다른 글
중첩 클래스 및 인터페이스 (안드로이드에서의 활용) (0) | 2024.01.17 |
---|---|
다형성 (0) | 2024.01.16 |
싱글톤 패턴 (0) | 2024.01.15 |
JAVA 데이터 타입 (0) | 2024.01.08 |