-
왜 엔티티를 반환하지 않고 DTO를 반환하는가 - 2개발 일지 2024. 10. 29. 20:32
앞서, 순환참조로 인해 엔티티를 반환하지 않고 DTO를 반환한다고 글을 작성했다.
그렇다면 어디서 순환참조가 발생하는지 먼저 알아야한다.
작성했던 예제를 디버깅해보면 요청시에 발생하는 것이 아니라 마지막으로 Controller에서 응답이 나갈 때 순홤참조 오류가 발생한다.
ex 메세지 하위에 cause 라는 항목을 보게 되면 JsonMappingException이 발생한다.
즉, 응답으로 나가야하는 Json 형식에 데이터를 매핑할 수 없다는 오류가 발생한다.
Jackson 라이브러리를 사용해서 객체를 -> Json으로 바꿔주는것 같은데 왜 에러가 발생했을까?
먼저, 해당 문제를 보기 전에 Spring Boot에서 기본으로 제공해주는 HttpMessageConverter에 대해서 간단하게 알고 넘어가자
HttpMessageConverter은 Spring Framework에서 HTTP 요청 본문을 Java 객체로 변환하거나, Java 객체를 HTTP 응답 본문으로 변환하는 역할을 담당하는 인터페이스이다.
이를 기본적으로 구현하는 구현체 클래스로는 여러개가 있지만, 대표적으로 몇개 작성해보자면 다음과 같다
- StringHttpMessageConverter: String 처리
- MappingJackson2HttpMessageConverter: JSON 처리
- Jaxb2RootElementHttpMessageConverter: XML 처리
HttpMessageConverter가 어떤 역할을 하는지 알았고, 이를 구현하는 구현체 클래스들이 어떤 것들이 있는지 알았으니 이제 다시 문제를 살펴보면
@RestController @RequiredArgsConstructor public class PostController { private final PostService postService; // 바로 엔티티 객체를 뿌려주면 연관관계에 있는 객체들끼리 순환참조를 이루게된다. (양방향 연관관계 문제) // 한쪽에서 jsonignore해줘야한다 @GetMapping("/test") public List<Post> test() { return postService.getPosts(); } }
/test 라는 GET 요청이 왔을 때 postService.getPosts()의 결과값을 Json 형식으로 Http 응답 본문에 전달하게 된다.
이때 HttpMessageConverter가 Json 형식으로 컨버팅하면서 오류가 발생하는 것이다.
이제 Jackson 라이브러리에서 어떻게 자바 객체를 Json 형식으로 컨버팅하는지 알면 이 문제를 어느 정도 파악할 수 있을 것 같다.
Spring 에서 컨트롤러가 리턴하는 값이 Json인 경우 MessageConverter API가 이를 후킹한 후, 리플렉션이라는 기술을 통해 Object Mapper을 사용해서 Json 객체로 만들고 난 후 Json 객체를 리턴해준다.
어떻게 Json 객체를 리턴해주는지는 알았으나, 그럼 어디서 문제인거지?
'개발 일지' 카테고리의 다른 글
왜 엔티티를 반환하지 않고 DTO를 반환하는가? (2) 2024.10.23 서버 도메인 없이 EC2 서버에 https 적용하기 (0) 2024.09.07 메소드 오버라이딩시 super 키워드 조심하기 (0) 2024.08.16 @Bean vs @Component (0) 2024.08.16 DB 작업시 @Transactional는 항상 써야할까? (0) 2024.06.28