[Jackson] 상속관계 serialize, deserialize

Jinny·2022년 6월 16일
0

스프링

목록 보기
4/5

프로젝트 진행중, Controller에서 Request Body로 받은 JSON객체 정보를 보고 상속관계의 클래스 중 적합한 클래스에 매핑하는 방법을 찾음.

(PostCreateDTO -> GeneralPostCreateDTO, ReviewPostCreateDTO 중 json 정보에서 reviewInfo 정보 유무에 따라 실제 클래스를 결정해야 했음)

@JsonTypeInfo

직렬화/역직렬화 시 포함할 타입 정보의 세부 사항을 나타냄. 즉, type에 따라 객체를 알맞은 타입으로 직렬화, 역직렬화 할 때 사용. 상속을 통해 다형성을 구현한 경우, 실제 클래스가 무엇인지 알려주는 설정을 할 수 있음.

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")면, json type이라는 메타정보를 생성하여 사용하고 이 메타정보는 json에 추가 프로퍼티로 들어간다.

속성으로 ID, AS, property, visible 등을 가짐

  • PostCreateDTO 구조
@Getter @Setter
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "postType", visible = true)
@JsonSubTypes({
        @JsonSubTypes.Type(value = ReviewPostCreateDTO.class, name = "REVIEW_POST"),
        @JsonSubTypes.Type(value = GeneralPostCreateDTO.class, name = "GENERAL_POST")
})
public class PostCreateDTO {
    private String title;
    private String content;
    private Integer boardId;
    private PostType postType;
    private Integer writerId;
}

@Getter @Setter
public class GeneralPostCreateDTO extends PostCreateDTO {
}

@Getter @Setter
public class ReviewPostCreateDTO extends PostCreateDTO{
    private Integer postId;
    private String productName;
    private CSName csName;
}
  • 아이템 추가할 때 보내는 JSON 데이터
### create general post
POST http://localhost:8080/post
Content-Type: application/json

{
  "title": "insert general post test",
  "content": "insert general post test",
  "boardId": 2,
  "writerId": 1,
  "postType": "GENERAL_POST"
}

### create review post
POST http://localhost:8080/post
Content-Type: application/json

{
  "title": "insert review post test",
  "content": "insert review post test",
  "boardId": 1,
  "writerId": 1,
  "postType": "REVIEW_POST",
  "productName": "까르보",
  "csName": "GS25"
}
  • use = JsonTypeInfo.Id.Name

    Id Enum 의 value로 직렬화 중에 식별자를 어떤 것으로 식별할지 정의

    use는 어노테이션이 위치한 클래스 및 하위 클래스 유형의 인스턴스에 대한 정보를 직렬화, 역직렬화할때 지정해야 하는 프로퍼티.

    즉, '나는 이 클래스를 직렬화할때 클래스명으로 식별하겠다' 라는 뜻

  • include = JsonTypeInfo.As.EXISTING_PROPERTY

    As Enum 의 value로 메타 데이터에 대한 표준 유형 방식을 정의.(JsonType.Id.NONE 제외) PROPERTY의 경우 POJO 방식으로 역직렬화 가능하게끔 해주는 값이며, EXISTING_PROPERTY를 사용할 경우 일반적인 접근(getter, setter)으로 역직렬화 및 직렬화 가능하게 해주는 값

    (기존 필드를 이용할 수 있음)

  • property = "postType"

    JsonTypeInfo.As.PROPERTY를 위한 속성. 위 예시의 경우 postType으로 클래스를 구분하기 때문에 postType으로 설정.

  • visible = true

    타입을 구분하는 식별자(postType)를 역직렬화하겠다는 의미. 이걸 따로 설정하지 않으면 postType을 역직렬화 하지 않음

  • @JsonSubTypes.Type(name = "XXX", value = XXX.class)

    직렬화 가능한 하위 클래스들의 타입을 표시하고, JSON에서 사용되는 논리적 이름을 연결하기 위해 JsonTypeInfo와 함께 사용되는 주석.

    .Type의 경우 이름 기반으로 하위 유형의 타입을 정의하고, name은 식별하기 위한 논리적 이름, value는 클래스를 명시.

출처

[Jackson] 상속관계 deserializing

Controller에서 다형성을 활용해 JSON 객체를 받아보자!

profile
삐약 응애

0개의 댓글