본문 바로가기

JAVA

Java - Jackson

= Jackson이란?

: Json, XML, YAML, CSV 등 다양한 확장자를 가지고 있는 데이터의 처리를 지원하는 라이브러리. 스트림 방식이므로 속도가 빠르고 유연하며, 다양한 third party 데이터 타입을 지원하며, annotation 방식으로 메타 데이터를 기술할 수 있다.

 

스프링부트에서는.. Json -> Object, Object -> Json 변환작업을 할 수 있도록 설정이 되어있는데

# Gradle 기준
implementation 'org.springframework.boot:spring-boot-starter-web'

spring-boot-starter-web에 jackson 라이브러리가 포함되어있다.

@RestController Annotation을 사용하는 경우, POJO Class들이 자동으로 Json포맷으로 변환할 때 이 라이브러리를 사용한다.

아래에 정리한 내용은 POJO 클래스를 JSON데이터로 변환시에, 사용할 수 있는 Annotation들이다.

 

물론, 해당 라이브러리를 직접 DI할 수도 있다.

implementation "com.fasterxml.jackson.core:jackson-core:2.11.4"
implementation "com.fasterxml.jackson.core:jackson-annotations:2.11.4"
implementation "com.fasterxml.jackson.core:jackson-databind:2.11.4"

= JAVA Object <-> Json

// POJO Class Example
public class PhotoDto {
    private int photoId;
    private String name;
    private String ownerName;
    private String createDt;
 
    public int getPhotoId() {
        return photoId;
    }
 
    public void setPhotoId(int photoId) {
        this.photoId = photoId;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getOwnerName() {
        return ownerName;
    }
 
    public void setOwnerName(String ownerName) {
        this.ownerName = ownerName;
    }
 
    public String getCreateDt() {
        return createDt;
    }
 
    public void setCreateDt(String createDt) {
        this.createDt = createDt;
    }
}
// Test
public static void main(String[] args) {
    PhotoDto photoDto = new PhotoDto();
    photoDto.setPhotoId(21);
    photoDto.setName("벚꽃사진");
    photoDto.setOwnerName("홍길동");
    photoDto.setCreateDt("2021-01-01 00:00:00");
 
 
    String jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(photoDto); // jsonFormat String으로 만들어준다.
    System.out.println(jsonString);
    PhotoDto resultDto = mapper.readValue(jsonString, photoDto.getClass()); // String to Object
 
 
    // {"photoId" : 21, "name" : "벚꽃사진", "ownerName" : "홍길동", "createDt" : "2021-01-01 00:00:00"}
}

- ObjectMapper Method 설명

  • writerWithDefaultPrettyPrinter() : json 데이터를 보기 좋게 출력
  • writeValueAsString(Object) : JavaObject로부터 JSON을 만들고 이를 문자열로 반환한다.
  • readValue(content, valueType) : 파일 혹은 json 문자열 등을 포함하는 content를 읽어서 valueType으로 변환한다.
  • writeValue(content, Object) : Object를 content형태로의 output으로 만들어준다.

= Annotation 정리

: POJO Class에 정의한다.

  • @JsonProperty : JSON으로 변환시 속성이름 변경 (ex) name필드를 newName으로 변경하고자 할 때 -> @JsonProperty("newName") )
  • @JsonIgnore : JSON으로 변환시 무시한다. (=필드를 제외)
  • @JsonIgnoreProperties : json으로 변환(Serialize, Deserialize)시 제외시킬 속성을 지정. VO class 위에서 선언
  • @JsonAnyGetter : Map 타입필드에 대해 JSON 변환시 key, value를 일반속성처럼 변환시켜준다.
@JsonAnyGetter 적용전
AS-IS
{
    "id" : 1,
    "info" : {
        "name" : "홍길동",
        "age" : 30
    }
}
 
 
@JsonAnyGetter 적용후
TO-BE
{
    "id" : 1,
    "name" : "홍길동",
    "age" : 30
}
  • @JsonAnySetter : 역직렬화시 JSON 속성을 map 필드에 대해 적용한다.
  • @JsonGetter : getter method에 정의한다. 어떤 필드값을 가져올 때, 지정된 메소드로 접근해서만 가져올 수 있도록 한다.
  • @JsonSetter : 역직렬화시 JSON 속성을 필드에 할당하기 위해 어떤 필드의 setter임을 지정한다.
  • @JsonPropertyOrder : serialization(직렬화) 순서를 정의한다. (= 필드 순서)
@JsonPropertyOrder({"age", "name", "id"}) -> 기본이 id, name, age 일때, 순서가 age, name, id로 바뀐다.
  • @JsonAutoDetect : 어떤 필드/메소드를 JSON으로 변활할지를 지정한다.
    (Visibility는 ANY, DEFAULT, NON_PRIVATE, NONE, PROTECTED_AND_PRIVATE, PUBLIC_ONLY (접근제어자 관련)값이 있다.)
  • @JsonInclude : 값 존재 유무에 따라 Serialize 시 동작을 지정 (default는 always)
    • ALWAYS : 속성의 값에 의존하지 말고 항상 포함
    • NON_EMPTY : null 또는 값이 빈 경우가 아니면 포함
    • NON_NULL : null이 아니면 포함
    • NON_DEFAULT : bean의 기본 생성자로 정의된 필드값과 다르게 변경된 필드만 포함
  • @JsonUnwrapped : serialize 혹은 deserialize 때 랩핑 해제/단조롭게 하는(?) 값을 정의한다. 즉, 어떤 필드에 대해 중첩 구조로 넣는다면 그렇게 하지 못하게 명시적으로 알린다.
  • @JsonRootName : VO class 위에 선언해서 wrapping 해서 json 변환
  • @JsonFormat : 날짜, 시간값을 직렬화할 때 형식을 지정 ex) @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-mm-yyyy hh:mm:ss")