본문 바로가기
프로그래밍/기타

DTO 직렬화 과정에서 PropertyNamingStrategy 사용하기

by 카프카뮈 2021. 3. 4.

프로젝트를 진행하면서 외부 서버와 통신할 일이 있는데, 이 과정에서 자잘한 스트레스를 받았다.

 

카카오에서 제공하는 Daum 검색 API로 책 관련 정보를 파싱받고 있다.

그런데, 여러 개의 도서 정보를 조회 시 주어지는 메타 정보 데이터가 다음과 같이 주어진다.

"meta": {
    "is_end": true,
    "pageable_count": 1,
    "total_count": 1
}

변수명이 Snake Case로 선언되어 있다.

보통 변수명을 지을 때는, 다음과 같은 케이스를 많이 사용한다.

  • 케밥 케이스 : 하이픈으로 단어를 연결한다. (예시 : is-end, pageable-count)
  • 스네이크 케이스 : 밑줄 문자로 단어를 연결한다. (예시 : is_end, pageable_count)
  • 카멜 케이스 : 첫 번째 단어는 소문자로, 두 번째 단어부터는 대문자로 적어 연결한다. (예시 : isEnd, pageableCount)
  • 이외에도 헝가리안 표기법, 파스칼 표기법 등이 있으나 여기서는 생략한다.

나는 변수명이나 메서드명을 카멜 케이스로 통일하여 작성하고 있다.

그런데 스네이크 케이스로 된 데이터 때문에, 내 DTO에 통일되지 않은 변수명을 쓰고싶지 않았다.

 

일단, DTO 코드를 다음과 같이 작성하고, 혹시 자동으로 번역해주진 않을지 테스트해본다.

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class BookMetadataDto {
    private Integer totalCount;
    private Integer pageableCount;
    private Boolean isEnd;
}

이대로 파싱을 진행해본 결과, 해당 값들을 직렬화하는 과정에서 누락하여 null이 들어간다.

파싱한 값을 반환한 뒤 postman에서 확인. null이 들어간다.


PropertyNamingStrategy

다행히 직렬화/역직렬화 과정에서 이런 문제를 해결하기 위해,

Jackson에서는 네이밍 전략(PropertyNamingStrategy)을 제공한다.

다음은 공식 문서 링크이다.

 

PropertyNamingStrategy (jackson-databind 2.7.0 API)

Class that defines how names of JSON properties ("external names") are derived from names of POJO methods and fields ("internal names"), in cases where they are not auto-detected and no explicit annotations exist for naming. Methods are passed information

fasterxml.github.io

제공하는 전략은 다음과 같다.

static PropertyNamingStrategy CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES

Deprecated. 

Since 2.7 use SNAKE_CASE instead;

static PropertyNamingStrategy KEBAB_CASE

Naming convention used in languages like Lisp, where words are in lower-case letters, separated by hyphens.

static PropertyNamingStrategy LOWER_CAMEL_CASE

Naming convention used in Java, where words other than first are capitalized and no separator is used between words.

static PropertyNamingStrategy LOWER_CASE

Naming convention in which all words of the logical name are in lower case, and no separator is used between words.

static PropertyNamingStrategy PASCAL_CASE_TO_CAMEL_CASE

Deprecated. 

Since 2.7 use UPPER_CAMEL_CASE instead;

static PropertyNamingStrategy SNAKE_CASE

Naming convention used in languages like C, where words are in lower-case letters, separated by underscores.

static PropertyNamingStrategy UPPER_CAMEL_CASE

Naming convention used in languages like Pascal, where words are capitalized and no separator is used between words.


PropertyNamingStrategy의 적용

이제 PropertyNamingStrategy를 사용해 이름 전략에 맞게 직렬화를 하도록 해보자.

DTO의 코드는 다음과 같다.

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class BookMetadataDto {
    private Integer totalCount;
    private Integer pageableCount;
    private Boolean isEnd;
}

스네이크 케이스로 된 값을 받아올 것이므로, @JsonNaming 어노테이션 내에 해당 네이밍 전략을 명시한다.

이제, 이대로 직렬화 과정을 진행해 본다.

적절한 값이 들어간 것을 확인.

진행해 본 결과, 올바른 값이 들어간 것을 확인했다.

하지만 이 로직은, 이 객체의 변수명을 해당 전략에 맞게 바꾼다 라는 의미를 가진다.

그런 탓에, 해당 DTO를 그대로 반환한 결과 스네이크 케이스로 이름이 반환되는 것을 확인할 수 있었다.

당연한 이야기이지만, Request와는 별도로 Response DTO 객체를 만들면 될 것이다.


Reference

Jackson Property - Custom PropertyNamingStrategy 적용

위의 게시물에서 큰 참조를 얻었다.

해당 게시물은 전략이 없는 경우 Custom PropertyNamingStrategy를 만드는 것까지 담고 있으니,

관심이 있다면 꼭 읽어보기를 권한다!!

반응형

댓글