ResponseBody에 null 객체 제외하는 방법

waterlyn·2023년 6월 21일
0
post-thumbnail

결론 먼저 보기 🎧

Jackson 라이브러리의 @JsonInclude 어노테이션을 사용하여 null일 경우 제외하도록 지정해서 해결했다!

반환하지 않았는데 왜 나오지? 🤔

여행기 공유 플랫폼을 리팩토링하면서 게시글을 상세조회하는 부분을 고치고 있었다.
여행기 공유 플랫폼 travel.zip (Github)

임시저장한 게시글을 작성자가 조회할 경우에는 일반적으로 게시글을 조회하는 것과 다르게 데이터를 반환하고 싶었다.

일반적인 사용자일 경우 해당 게시글이 좋아요가 눌러져 있는지, 조회수가 몇인지, 북마크를 했는지 등의 부가적인 정보를 반환하고,
임시저장인 게시글을작성자가 조회한 경우에는 이러한 정보가 필요 없고, 다시 작성해야 하는 필수 필드만 반환해주면 된다.

그래서 처음에는 단순히 필요없는 필드를 반환해주지만 않으면 될 것이라고 생각하고 다음과 같이 코드를 작성했다.

public static TravelogueDetailRes toTravelougeDetailRes(
..., Long countLikes, Boolean isLiked, Boolean isBookmarked, Long viewCount){
		return new TravelogueDetailRes(...);
	} // 일반 공개된 게시물을 조회하는 경우 사용하는 정적 팩토리 메소드
    
public static TempTravelogueDetailRes toTempTravelogueDetailRes(
...){
	return new TravelogueDetailRes(...);
    } // 작성자가 자신의 임시 저장 글을 조회하는 경우 사용하는 정적 팩토리 메소드

_자, 이렇게 작성했으니 완벽해! 정적 팩토리 메소드로 분리할 생각을 하다니~ 나 좀 굉장한걸? 이라고 생각했는데 결과는 ...

위의 Json 결과는 작성자가 자신의 임시저장한 글을 조회했을 때 나타나는 결과이다. 의도한대로라면 countLikes, viewCount, bookmarked가 필드에 나타나면 안되는데 (생성자에 없으니까) 왜 나타나지? 라고 생각했는데, null 값을 그대로 보이면서 나타내고 있는 것이다....

답은 Jackson 라이브러리에 있었다. 🥷🏻

@ResponseBody를 통해서 응답 객체를 전달할 때 스프링은 내부적으로 Jackson 라이브러리를 사용하는데, Jackson도 결국 ObjectMapper를 사용하여 Json으로 객체를 파싱한다.

Jackson 라이브러리는 Json 형태의 데이터와 Java의 객체 형태의 데이터를 편리하게 자동으로 파싱하는 기능을 제공한다.

기본적으로 ObjectMapper는 자바의 프로퍼티를 사용해서 파싱할 값을 파악하고, Java는 프로퍼티를 객체 내의 생성자, 필드가 아닌 Getter를 통해 파악한다.

내가 DTO 클래스 내에 Getter를 만들어두었기 때문에 내가 생성자든, 필드를 사용해서 분리하려고 해도 Getter로 찾아내고 있었기 때문에 모든 파라미터를 Json으로 반환하고 있었던 것이다.
그래서 null 값을 가진 필드를 전달하지 않는 방법은 없을까 구글링해보다가 Jackson 라이브러리가 그러한 편의도 제공하고 있음을 알게 되었다!!

@JsonInclude

@JsonInclude는 serialize할 때 null, ""과 같은 값에 대해 원할 때에 반환할 수 있도록 지정할 수 있는 속성을 제공한다.

속성에는

  • Include.NON_NULL
  • Include.ALWAYS
  • Include.CUSTOM
  • Include.NON_DEFAULT
  • Include.USE_DEFAULT
  • Include.NON_EMPTY
  • Include.NON_ABSENT

가 있다.

이 중에서 내가 사용한 것은 Include.NON_NULL이고, 이 속성은 NULL이 아닌 경우에 반환하도록 하는 옵션이다.
이 옵션을 DTO 객체 내부 클래스 변수에 설정해주었다.

그러고 다시 결과를 확인해보니

원하는 필드가 잘 사라져 있는 것을 확인할 수 있었다!


사실은 가장 많이 사용하고 있던 라이브러리인데, 제대로 알고 있지 못해서 이렇게 조금은 헤맸던 것 같다. 이번 기회로 좀 더 알게 된 것 같아 조금은 뿌듯하다!! 🙌🏻

참고

공식문서

profile
Hello there 🖤

0개의 댓글