RestController에서 Entity를 ResponseDto로 변환하여 응답값을 반환하는 상황이다.
Dto has a Entity 구조로 만들어보았다.
각 getter 메소드를 다시 코딩하는 것으로 변화하는 상황에 대응할 수 있다?
잘 이해가 되지 않아 코드를 작성해보았다.
[코드]
public class CreateProductResponseDto {
@JsonIgnore
private Product product;
public CreateProductResponseDto(Product product) {
this.product = product;
}
public Long getId() {
return this.product.getId();
}
public String getName() {
return this.product.getName();
}
public String getMaker() {
return this.product.getMaker();
}
public Integer getPrice() {
return this.product.getPrice();
}
public String getImageUrl() {
return this.product.getImageUrl();
}
}
[결과]
CreateProductResponseDto
에는 id, name, maker등의 변수를 선언하지 않고 오로지 Entity 하나만 선언하고 각 getter만 재정의를 해줬다.
그런데 어떻게 별다른 변수가 없이 값이 잘 반환될까?
내 상식에서는 이해가 되지 않아 궁금증을 참지 못하고 무작정 IntelliJ의 Force step into 기능을 사용하여 코드를 까보았더니 딱 눈에 들어온 친구가 있었다. // inlined 'get()'
?
뭔가 게터를 호출한다고 외치고 있는 주석인 것 같았다.
이 다음으로 디버깅을 넘겨보니 아래와 같이 CreateProductResponseDto
에 한 getter로 이동했다!
위에서 CreateProductResponseDto
의 한 getter를 호출하는 객체는 jackson-databind 라이브러리 패키지에 있는 것을 확인했다.
구글링을 통해 해당 블로그에서 Jackson에 관한 해답을 찾았다.
@JsonProperty
를 사용하여 지정해주면 된다.그렇다면 Controller 반환 시에 왜 Jackson을 사용할까?
기존에 알고있던 내용으로는 RestController는 값을 반환할 때, 기존 Controller와는 다르게 ViewResolver
대신 MessageConverter
를 통해 알맞은 응답 형태로 리턴한다.
이 때 Content-Type
이 application/json
이라면 Jackson을 사용하는 것으로 알고 있었다.
추가적인 정보 및 확인은 토비의 스프링 2권 615~616쪽과 해당 블로그에서 찾아보았다.
application/json
콘텐츠 타입으로 전달되는 요청은 MappingJackson2HttpMessageConverter
을 통해 메서드 반환 타입 오브젝트로 변환된다.[결론]
Controller가 반환할 때 Jackson에 의해 CreateProductResponseDto
의 모든 프로퍼티(getter)가 호출되므로 별다른 변수를 선언하지 않아도 정상적으로 반환하는 것이었다!
이유를 알았으니 한번 더 따로 테스트를 해보자.
테스트 코드를 짤까 하다가, 직관적으로 반환된 데이터를 보고 싶어서 실제 Spring으로 진행하였다.
아래에서 프로퍼티(getter)는 3개의 정상 getter와 1개의 비정상 코드를 집어넣어봤다!
[코드]
public class CreateProductResponseTest {
public CreateProductResponseTest(Product product) {
}
public Long getIdTestHolyMoly() { // 정상
return 500L;
}
public String getNameTestMolyHoly() { // 정상
return "기범 최고";
}
public String getMakerWowAmazing() { // 정상
return "안양 최고";
}
public Integer ohMyGod() { // 비정상 (get으로 시작하지 않음)
return 5000000;
}
}
[결과]
앞에 get으로 시작하는 프로퍼티들은 정상적으로 반환되고, ohMyGod()
은 데이터 매핑에서 제외된 것을 볼 수 있다.