DTO 직렬화 에러 / DTO와 @Getter 개념/Type definition error: --No serializer found for class --and no properties discovered to create BeanSerializer

woniwon·2023년 7월 28일

Spring

목록 보기
4/8

When?

카카오 쇼핑몰 클론코딩을 진행하며 주문하기 기능을 구현하던 도중, POSTMAN을 활용해 "localhost:8080/orders/1"를 요청 했는데, 아래와 같은 오류가 발생했다.

오류 수정 방법

오류 코드를 보며 내가 알 수 있는건 DTO쪽의 문제라는 것과 직렬화와 관련된 문제라는 것이였다. 내가 건든 코드는 OrderService, OrderController, OrderResponse 였고, 모든 코드를 확인을 해봤지만 어디가 문제인지 못찾겠어서 결국 멘토님께 SOS를 했다!

결론은, DTO 직렬화 문제로 @GETTER가 없어서 발생한 오류였다.

진짜 코드를 다시 살펴보니 OrderResponse에서 SaveDTO 앞에 @Getter를 선언하지 않았고, 넣어주니 잘 실행되었다.

그냥 항상 DTO를 작성할 때는 @Getter과 @Setter를 무의식적으로 넣었던게 이렇게 화를 불러일으켰다..🥹
그래서 다시 DTO와 Getter, Setter의 개념을 정리해볼까 한다.

DTO란?

DTO (Data Transfer Object, 데이터 전송 객체)는 프로세스 사이에서 데이터를 이동하기 위한 객체로 중요한 정보를 노출시키지 않고 두 시스템 간 통신을 원할하게 할 수 있다.

  • Request DTO : 서버에서 수신

  • Response DTO : 서버에서 반환

  • DTO는 계층간 데이터 교환이 이루어질 수 있도록 하는 객체로 특별한 로직을 가지지 않는 순수한 데이터 객체이다

  • 또한, 굳이 Setter를 이용해 값을 수정할 필요 없이, 생성자를 이용해 값을 할당한다.

  • DTO는 SPRING에 의해 자동으로 직렬화/ 역직렬화 된다.

@Getter과 @Setter

두 어노테이션은 모두 Lombok이 제공하는 것으로, 클래스 내의 멤버 변수에 대한 Getter와 Setter 메서드들을 자동으로 생성해준다.

Getter 메서드

  • 객체의 필드 값을 반환하는 메소드로, 주로 필드 값을 읽고 사용하고자 할 때 사용한다.
    아래 코드에서, getName()이 이에 해당한다.
  • @Getter를 사용하면 getName()을 자동으로 생성해준다.
public class Person {
    private String name;

    public String getName() {
        return name;
    }
}

Setter 메서드

  • 객체의 필드 값을 변경 (Set)하는 메서드이며, 주로 필드에 값을 할당할때 사용한다.
    아래 코드에서, setName()이 이에 해당한다
  • @SEtter를 사용하면 setName()을 자동으로 생성해준다.
public class Person {
    private String name;

    public void setName(String name) {
        this.name = name;
    }
}

Getter와 Setter를 이용해 객체 필드에 접근할 때 필드의 접근 권한을 제어해, 데이터를 보호할 수 있다.

➕ Getter와 Setter를 사용하는 이유는, 데이터를 보호하기 위함이다.
데이터를 불러올 때 한번 더 가공하는 과정을 거쳐 내부 데이터가 결함을 가지지 않도록 하는 것 이다.(무결성) 그러나 무분별한 Setter은 데이터 무결성을 해칠 수 있다. (setter로 데이터를 수정하면, 어떤 부분을 수정하는제, 어디서 데이터를 수정하는지 알 수 없다) 그래서 이를 해결하기 위해 객체를 생성하는 생성자와, 이를 표현하는 메소드를 분리하여 사용하는 Builder 패턴을 이용해서 데이터 조금 더 직관적인 코드를 작성할 수 있다.

DTO에서 @Getter의 역할

  • Spring에서 Controller 계층과 Service 계층 사이의 데이터 전송을 위해 DTO를 사용한다.

  • 요청에 따른 응답을 반환할 때 DTO 객체를 다른 데이터 형식으로 변환시켜줘야 하는데, Spring은 Jackson 라이브러리를 사용하여 Json 데이터들을 직렬화 / 역직렬화 작업을 진행한다. (DTO <-> Json)
    이처럼 Spring에서 개발자 대신 데이터 변환을 해주기 위해 ResponseDto의 데이터 호출하게 되고, 이를 위해 getter 메소드가 필요하다.

  • 대부분의 필드는 private로 사용하여 접근을 막는다.
    그래서 외부에서 사용하기 위해서는 getter가 필요하다.

DTO 관련 참고 자료1
DTO 관련 참고 자료2

profile
단순 기록용 Velog 입니다.

1개의 댓글

comment-user-thumbnail
2023년 7월 28일

잘 읽었습니다. 좋은 정보 감사드립니다.

답글 달기