[Java] Jackson 라이브러리 자주 사용하는 기능 정리

728x90

 

들어가며


위 Jackson 라이브러리는 Spring 에서 객체를 직렬화, 역직렬화 할 때 필수 라이브러리이다.

위 라이브러리를 사용 안하는 백엔드 개발자는 없을 것? 이라고 생각한다.

 

회사 코드를 보다가 자주 보이는 것이지만, 매번 검색하는 번거로움을 줄이기 위해 정리를 해놓으려고 한다.

 

https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind

 

Jackson 라이브러리를 사용하기 위해선 위 URL 에 접속해서 gradle or Maven 본인이 사용하는
빌드 도구 코드를 따서 의존성 주입을 시키면 된다.

 

Gradle

// https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.17.2'

 

Maven

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.17.2</version>
</dependency>

 

Build 속도부터 해서 Gradle 이 많이 발전하고 있으므로 BuildMaven 을 사용해야하는 특수한 이유가 있는 것 아니면

Gradle 을 사용하자..

 

 

본론


 

모든 예시 클래스는 아래로 통일 합니다.

@AllArgsConstructor 
@NoArgsConstructor
@Getter @Setter @ToString
public class People {

    private String name;
    private Integer age;
    private Double height;
    private Address address;

}

 

@AllArgsConstructor
@NoArgsConstructor
@Getter @Setter @ToString
public class Address {
    private String street;
    private String city;
}

 

편의를 위해 Lombok 라이브러리를 사용하여 귀찮은 작업들을 해둔 상태 입니다.

 

위 객체를 이제 직렬화를 시킬 것 입니다. 

 

간단한 설명을 하자면 Jackson 라이브러리에 ObjectMapper 클래스를 통하여 직렬화, 역직렬화를 진행할 수 있습니다.

ObjectMapper objectMapper = new ObjectMaaper();

// 객체 -> Json [직렬화] 
objectMapper.readValue(); 

// Json -> 객체 [역직렬화] 
objectMapper.wirteAsvalue();

 

 

이제 본격적으로 Jackson 라이브러리에 유용한 어노테이션을 알아보겠습니다.

 

@JsonAlias

@JsonAlias는 JSON의 여러 필드 이름을 하나의 Java 필드에 매핑하고 싶을 때 사용됩니다. 예를 들어, JSON에서 name 또는 full_name 필드를 모두 name 필드에 매핑하고 싶을 때 사용합니다.

 

public class People {
    @JsonAlias({"full_name", "name"})
    private String name;
    private Integer age;
    private Double height;
    private Address address;
}

// 예제 JSON
String json = "{ \"full_name\": \"HyeonKyu\", \"age\": 25, \"height\": 180.5, \"address\": { \"street\": \"123 Gangnam\", \"city\": \"Seoul\" } }";

 

직렬화 결과

{
    "name": "HyeonKyu",
    "age": 25,
    "height": 180.5,
    "address": {
        "street": "123 Gangnam",
        "city": "Seoul"
    }
}

 

@JsonUnwrapped

 

@JsonUnwrapped는 중첩된 객체를 직렬화 및 역직렬화할 때 자주 사용하며, 중첩된 객체의 필드를 상위 객체의 필드처럼 평평하게 표현하고 싶을 때 사용합니다.

 

즉 Object 로 된 필드를, Json 에서 Obejct 로 감싸는게 아닌, 필드 자체를 Key 로 보여주는 것 입니다.

(말 그대로 Json 을 감싸지 않는다)

public class People {
    private String name;
    private Integer age;
    private Double height;

    @JsonUnwrapped
    private Address address;
}

// 예제 객체
People people = new People("Jin", 30, 180.5, new Address("123 Gangnam", "Seoul"));
{
    "name": "Jin",
    "age": 25,
    "height": 180.5,
    "street": "123 Gangnam",
    "city": "Seoul"
}

 

@JsonProperty

 

@JsonProperty는 JSON 필드와 Java 객체의 필드를 매핑할 때 사용됩니다.

필드 이름을 명시적으로 지정하거나, 특정 필드만 직렬화/역직렬화하고 싶을 때 사용됩니다.

 

즉 필드 이름은 name 이지만, Json 에서는 좀 더 명시적인 값 또는 API 명세에 따라 정해진 이름이 있을 떄 사용합니다.

 

public class People {
    @JsonProperty("full_name")
    private String name;
    private Integer age;
    private Double height;
    private Address address;
}

// 예제 객체
People people = new People("JinHyeonkyu", 25, 180.5, new Address("123 Gangnam", "Seoul"));
{
    "full_name": "JinHyeonKyu",
    "age": 25,
    "height": 180.5,
    "address": {
        "street": "123 Gangnam",
        "city": "Seoul"
    }
}

 

@JsonManagedReference , @JsonBackReference

 

@JsonManagedReference와 @JsonBackReference는 순환 참조 문제를 해결하는 데 사용됩니다.

부모-자식 관계에서 부모 객체는 @JsonManagedReference 로,

자식 객체는 @JsonBackReference로 어노테이션 을 사용 하여 순환 참조를 방지할 수 있습니다.

 

public class People {
    private String name;
    private Integer age;
    private Double height;

    @JsonManagedReference
    private Address address;
}

public class Address {
    private String street;
    private String city;

    @JsonBackReference
    private People resident;
}

// 예제 객체
People people = new People("Jin", 25, 180.5, new Address("123 Gangnam", "Seoul"));
people.getAddress().setResident(people);
{
    "name": "Jin",
    "age": 25,
    "height": 180.5,
    "address": {
        "street": "123 Gangnam",
        "city": "Seoul"
    }
}

 

 

 

 

 

결론


역시 내 머리에 기록을 하는게 아닌 곳에 기록을 해야지 좋은 것 같다.

기억보단 기록 하는 습관을 들이자!

 

++ 나중에 모르는게 생길 때 마다 추가적으로 업데이트를 해야겠다.. 

 

 

 

 

참조


https://pjh3749.tistory.com/281
com.fasterxml.jackson
https://github.com/FasterXML/jackson-databind/tree/2.18/src/main/java/com/fasterxml/jackson/databind

 

 

728x90