1. 문제
@RestController
public class MemberController {
// 로그인 되어 있는지 여부 확인
@PostMapping("/islogined")
public void isLogined(@RequestBody MemberDTO memberDTO){
// boolean 타입
System.out.println("isLogined 의 값은 : " + memberDTO.isLogined());
// Boolean 타입
System.out.println("isLogined 의 값은 : " + memberDTO.getIsLogined());
}
}
JSON 데이터를 DTO로 변환할 때, Jackson 라이브러리를 사용한다. 여기서 Jackson 라이브러리는 Spring이 기본적으로 사용하는 json 기본 라이브러리이다.
@Data
@NoArgsConstructor
@AllArgsConstructor
public class MemberDTO {
private boolean isLogined;
}
위는 기본형이고
@Data
@NoArgsConstructor
@AllArgsConstructor
public class MemberDTO {
private Boolean isLogined;
}
위는 참조형이다.
{
"isLogined" : "true"
}
같은 data로 DTO를 맵핑해 필드값을 출력 한다고 할 때 기본형(boolean)과 참조형(Boolean)의 처리에 차이가 있을까?
정답은 위는 'false'가 출력되고, 아래는 'true'가 출력된다.
띠요잉,,,???
2. 문제 원인
Jackson이 DTO 필드 이름을 맵핑 할 때 is가 있으면 is를 떼고 맵핑 하려고 한다.
1. DTO에서 Getter/Setter가 있는 경우, 해당 메서드 이름을 기반으로 필드 추론
2. boolean의 getter 네이밍 생성은 필드명이 isLogined, logined던 간에 isLogined( )로 동일
3. getter의 isLogined( ) 앞에 is를 떼고 logined 필드가 있을거라 생각
4. JSON으로 넘어온 key값 이름이 "isLogined"이므로 불일치
5. isLogined( )는 기본형으로 초기값이 false 이므로 false 출력
{
"isLogined" : "true"
}
{
"logined" : "true"
}
위 결과의 출력은 어떻게 될까?
결과는 위는 false가 출력되고 아래는 true가 출력된다.
** 24/12/03 수정
getter로 콘솔에는 출력이 되는데 { "logined" : "true" }이 실제로 DB에 저장되는지 궁금했다.
1. API 호출하기
{ "logined" : "true" } 값을 전달한다.
2. API에서 콘솔 출력하기
@Data
@NoArgsConstructor
@AllArgsConstructor
public class MemberDTO {
private boolean isLogined;
}
JSON의 "logined"와 DTO의 isLogined가 맵핑 된다.
3. DB 저장 값 확인하기
값이 true로 들어간다.
현재 포스트를 작성하는데 엄청 헷갈린다. 따라서 boolean 변수명에 is를 쓰지 말아야겠다.
3. 문제 해결
⭐⭐⭐ 1. 필드 앞에 is 쓰지 말기 즉 isLogined, isChecked 대신 loginStatus, checkStatus로 사용하기
2. 기본형 boolean이 아닌, 참조형 Boolean 사용
3. @JsonProperty 에너테이션 사용
@Data
@NoArgsConstructor
@AllArgsConstructor
public class MemberDTO {
@JsonProperty("isLogined")
private boolean isLogined;
}
명시적으로 해당 "isLogined"와 맵핑 되도록 만들 수 있다.
[결론] : 헷갈릴 때 임시 방편으로 3번 사용하고, Java에서 boolean 타입 변수명 접두사에 is 붙이지 말자.
'JPA' 카테고리의 다른 글
[JPA] JSON 직렬화 순환참조, JSON 무한출력, JSON 와르르 (0) | 2024.10.22 |
---|